Skip to content

Instantly share code, notes, and snippets.

@diegomelo182
Created March 2, 2017 16:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegomelo182/76385da60772b6f4f409df8fa4965cb1 to your computer and use it in GitHub Desktop.
Save diegomelo182/76385da60772b6f4f409df8fa4965cb1 to your computer and use it in GitHub Desktop.
Angular 2 - Rest API Service
class ApplicationController < ActionController::API
before_action :jwt_auth_validation
def jwt_auth_validation
jwt_token = request.headers['Authentication']
if jwt_token
token_decoded = jwt_decode(jwt_token)
if !token_decoded.first.nil? && !token_decoded[0][:auth].nil? && token_decoded[0][:auth]
render json: { error: 'Authentication error, token is wrong on header Authentication' }, status: :unauthorized
return;
elsif !token_decoded.first.nil? && !token_decoded[0][:exp].nil? && token_decoded[0][:exp]
render json: { error: 'Authentication error, token expired.' }, status: :unauthorized
return;
elsif token_decoded.length>1 && jwt_invalid_payload(token_decoded[0])
render json: { error: 'Authentication error, invalid payload.' }, status: :unauthorized
return;
elsif token_decoded.length>1 && !jwt_invalid_payload(token_decoded[0]) && token_decoded[0]['request_type'] == 'password_recovery'
# password recovery token verification
unless request.original_fullpath.index('/users/'+token_decoded[0]['user_id'].to_s) == 0
render json: { error: 'Permission error, action unauthorized.' }, status: :unauthorized
return;
end
end
# renew token
if token_decoded.length>1
renewed_payload = token_decoded.first
if !renewed_payload['exp'].nil?
time_start = Time.at(renewed_payload['exp']) - 1.hours
time_end = Time.at(renewed_payload['exp'])
time_now = Time.now.to_i
if time_now >= time_start.to_i && time_now <= time_end.to_i
renewed_payload['exp'] = 4.hours.from_now.to_i
response.headers['JWT-Token-Renewed'] = jwt_encode(renewed_payload)
end
end
end
else
render json: { error: 'Authentication error, token is missing on header Authentication' }, status: :unauthorized
return;
end
end
private
def jwt_decode(token, secure = true)
begin
if secure
token = JWT.decode token, Rails.application.secrets.hmac_secret, true, { :algorithm => 'HS256' }
else
token = JWT.decode token, nil, false
end
rescue JWT::ExpiredSignature
token = [ { exp: true, auth: false } ]
rescue
token = [ { exp: false, auth: true } ]
end
return token
end
def jwt_encode(payload, secure = true)
if secure
return JWT.encode payload, Rails.application.secrets.hmac_secret, 'HS256'
end
return JWT.encode payload, nil, 'none'
end
def jwt_invalid_payload(payload)
return (!payload['token_type'].nil? && payload['token_type'] != 'client_a2') || (!payload['token_type'].nil? && payload['token_type'] != 'client_a2' && !payload['request_type'].nil? && payload['request_type'] != 'password_recovery')
end
end
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Http, Response, Headers, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { LocalStorageService } from 'angular-2-local-storage';
import 'rxjs/add/operator/toPromise';
import {
AppHelper,
AppConstants
} from '../helpers';
export class DefaultService {
public endPoint: string;
constructor(
public http: Http,
public localStorageService: LocalStorageService,
public router: Router,
) { }
// GET /end-point
public getAll(query_object: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+this.endPoint;
let params = query_object ? '?'+AppHelper.objectToQueryString(query_object) : '';
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.get(url+params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// GET /end-point/:id
public getById(id: number, query_object: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+this.endPoint+'/'+id;
let params = '?'+AppHelper.objectToQueryString(query_object);
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.get(url+params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// POST /end-point/
public create(query_object: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+this.endPoint;
let params = JSON.stringify(query_object);
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.post(url, params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// PUT /end-point/:id
public update(id: number, query_object: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+this.endPoint+'/'+id;
let params = JSON.stringify(query_object);
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.put(url, params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// DELETE /end-point/:id
public delete(id: number): Observable<any> {
let url = AppConstants.wpApiDevUrl+this.endPoint+'/'+id;
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.delete(url, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// DELETE /your-url
public getDataByUrl(urlRequest: string, getParams: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+urlRequest;
let params = '?'+AppHelper.objectToQueryString(getParams);
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.get(url+params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// POST /your-url
public postDataByUrl(urlRequest: string, getParams: any = {}): Observable<any> {
let url = AppConstants.wpApiDevUrl+urlRequest;
let params = JSON.stringify(getParams);
// JWT
let options: RequestOptionsArgs = { headers: this.getJWTHeaders() };
return this.http.post(url, params, options)
.map((res: Response): Observable<any> => {
this.setJWTHeaders(res); // renew token
let response;
if(res.text()) {
response = res.json();
}
return response || {};
})
.catch((error: Response | any) => {
return Observable.throw(error);
});
}
// set JWT Header
private getJWTHeaders(): Headers {
return new Headers({
'Content-Type': 'application/json',
'Authentication': this.localStorageService.get('token'),
});
}
// get JWT Header
private setJWTHeaders(response: Response): void {
if(response.headers.get('JWT-Token-Renewed')){
this.localStorageService.set('token', response.headers.get('JWT-Token-Renewed'));
}
}
}
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { LocalStorageService } from 'angular-2-local-storage';
import { Router } from '@angular/router';
import { DefaultService } from './default.service';
@Injectable()
export class UsersService extends DefaultService {
public endPoint: string = 'users';
constructor(
public http: Http,
public localStorageService: LocalStorageService,
public router: Router,
) {
super(http, localStorageService, router);
}
}
class UsersController < ApplicationController
before_action :set_user, only: [:show, :update, :destroy]
skip_before_action :jwt_auth_validation, only: [:login, :logoff, :recovery_password]
# GET /users
# GET /users.json
def index
@users = User.eager_load(:rule)
render json: @users
end
# GET /users/1
# GET /users/1.json
def show
render json: @user
end
# POST /users
# POST /users.json
def create
@user = User.new(user_params)
if @user.valid?
if @user.save
UsersMailer.create(@user, params[:user][:password]).deliver_later
render json: @user, status: :created, location: @user
else
render json: @user.errors, status: :unprocessable_entity
end
else
render json: @user.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
@user = User.find_by(id: params[:id])
if @user.update(user_params)
head :no_content
else
render json: @user.errors, status: :unprocessable_entity
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
@user.destroy if @user
head :no_content
end
def login
if params[:username] && params[:password]
# login by username
user = User.find_by(username: params[:username])
if user
if BCrypt::Password.new(user.password_digest) == params[:password]
payload = {
'user_id' => user.id,
'token_type' => 'client_a2',
'exp' => 4.hours.from_now.to_i,
}
token = jwt_encode(payload)
render json: { token: token }, status: 200
else
render json: { error: "Usuário/Email ou senha incorretos, por favor tente novamente mais tarde."}, status: :unauthorized
end
else
#login by email
user = User.find_by(email: params[:username])
if user
if BCrypt::Password.new(user.password_digest) == params[:password]
payload = {
'user_id' => user.id,
'token_type' => 'client_a2',
'exp' => 4.hours.from_now.to_i,
}
token = jwt_encode(payload)
render json: { token: token }, status: 200
else
render json: { error: "Usuário/Email ou senha incorretos, por favor tente novamente mais tarde."}, status: :unauthorized
end
else
render json: { error: "Usuário/Email ou senha incorretos, por favor tente novamente mais tarde."}, status: :unauthorized
end
end
else
render json: { error: "Por favor preencha os campos corretamente."}, status: :unauthorized
end
end
def recovery_password
if params[:email]
user = User.find_by(email: params[:email])
if user
payload = {
'user_id' => user.id,
'token_type' => 'client_a2',
'request_type' => 'password_recovery',
'exp' => 30.minutes.from_now.to_i,
}
token = jwt_encode(payload)
UsersMailer.recovery_password(user, token).deliver_later
render json: { success: 'Enviamos um email com o link para a alteração da senha da sua conta, favor verificar sua caixa de entrada.' }, status: 200
else
render json: { error: "O email informado não está cadastrado no nosso sistema." }, status: :unauthorized
end
else
render json: { error: "Por favor preencha o campo de email corretamente." }, status: :unauthorized
end
end
private
def set_user
@user = User.find_by(id: params[:id])
end
def user_params
params.require(:user).permit(:name, :username, :email, :password, :password_confirmation, :avatar, :bday, :gender, :rule_id)
end
end
@rafaelss95
Copy link

Awesome! Thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment