Skip to content

Commit

Permalink
feat: refresh token
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikadows committed May 25, 2022
1 parent 98691db commit 39bfc4c
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/components/Auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { useToasts } from 'react-toast-notifications';
import { useTranslation } from 'react-i18next';
import { isAuthorized, logout } from '../../hooks/auth/access/access';
import { Role } from '../../hooks/auth/access/Roles';
import { useRefreshToken } from '../../hooks/auth/refreshToken';

const Login: React.FC = () => {
const { t } = useTranslation();
const { addToast } = useToasts();
const navigate = useNavigate();
const { token, setToken } = useToken();
const { setRefreshToken } = useRefreshToken();

useEffect(() => {
if (token) {
Expand All @@ -40,7 +42,8 @@ const Login: React.FC = () => {

try {
const response = await login(request);
setToken(response);
setToken(response.token);
setRefreshToken(response.refreshToken);
const isAuthorize = isAuthorized(Role.ADMIN);
if (!isAuthorize) {
logout();
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/auth/access/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function isAuthorized(role: Role): boolean {

export function logout() {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
}

export function parseJwt(token: string): DecodedToken {
Expand All @@ -24,3 +25,7 @@ export function parseJwt(token: string): DecodedToken {
const base64 = base64Url.replace('-', '+').replace('_', '/');
return JSON.parse(window.atob(base64));
}

export function cleanToken(token: string): string {
return token.slice(7);
}
23 changes: 23 additions & 0 deletions src/hooks/auth/refreshToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useState } from 'react';

function getRefreshToken(): string {
const tokenString = localStorage.getItem('refresh_token');
if (tokenString) {
return tokenString;
}
return '';
}

function useRefreshToken() {
function setRefreshToken(userToken: string) {
localStorage.setItem('refresh_token', userToken);
}
const [refreshToken] = useState(getRefreshToken());

return {
setRefreshToken,
refreshToken,
};
}

export { getRefreshToken, useRefreshToken };
6 changes: 3 additions & 3 deletions src/hooks/auth/register.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { commonRequest, loginRequest } from '../common/request';
import LoginRequest from './requests/LoginRequest';
import LoginResponse from './responses/LoginResponse';

const login = async (request: LoginRequest): Promise<string> => {
const token = await loginRequest({
const login = async (request: LoginRequest): Promise<LoginResponse> => {
return await loginRequest({
url: `/auth/login`,
method: 'POST',
data: {
username: request.username,
password: request.password,
},
});
return token.slice(7);
};

const register = async (
Expand Down
9 changes: 9 additions & 0 deletions src/hooks/auth/responses/LoginResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default class LoginResponse {
token: string;
refreshToken: string;

constructor(token: string, refreshToken: string) {
this.token = token;
this.refreshToken = refreshToken;
}
}
30 changes: 26 additions & 4 deletions src/hooks/common/request.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import axios, { AxiosRequestConfig } from 'axios';
import { getToken } from '../auth/token';
import LoginResponse from '../auth/responses/LoginResponse';
import { cleanToken, logout } from '../auth/access/access';
import { getRefreshToken } from '../auth/refreshToken';

const client = axios.create({
baseURL: process.env.REACT_APP_API_ENDPOINT,
Expand All @@ -12,7 +15,21 @@ const authenticatedRequest = (options: AxiosRequestConfig) => {
// commonRequest(options);
const onSuccess = (response: any) => response;
const onError = (error: any) => {
// optionaly catch errors and add some additional logging here
if (error.response.status === 403) {
client.defaults.headers.common.Authorization = `Bearer ${getRefreshToken()}`;
client({ timeout: 5000, url: `/auth/refresh/token`, method: 'GET' })
.then((response: any) => {
localStorage.setItem(
'access_token',
cleanToken(response.headers['authorization']),
);
})
.catch((error: any) => {
logout();
return error;
});
}
// optionally catch errors and add some additional logging here
return error;
};

Expand All @@ -28,7 +45,7 @@ const commonRequest = (options: AxiosRequestConfig) => {
};
const onError = (error: any) => {
throw error;
// optionaly catch errors and add some additional logging here
// optionally catch errors and add some additional logging here
// return error;
};

Expand All @@ -38,10 +55,15 @@ const commonRequest = (options: AxiosRequestConfig) => {
};

const loginRequest = (options: AxiosRequestConfig) => {
const onSuccess = (response: any) => response.headers['authorization'];
const onSuccess = (response: any) => {
return new LoginResponse(
cleanToken(response.headers['authorization']),
cleanToken(response.headers['refresh-token']),
);
};
const onError = (error: any) => {
throw error;
// optionaly catch errors and add some additional logging here
// optionally catch errors and add some additional logging here
// return error;
};

Expand Down

0 comments on commit 39bfc4c

Please sign in to comment.