React Network request Interconnect login API
The front store
localstorage
The data stored by the localStorage method has no time limit
Storage mode:
It is permanently stored in key-value pairs and never loses validity unless manually deleted
Commonly used API:
GetItem // Obtain records
SetIten // Save the record
RemoveItem // Removes the record
Clear // Clear records
sessionstorage
HTML5 localStorage API localStorage and sessionStorage are used in the same way
The difference is that sessionStorage is cleared as soon as the page is closed, while localStorage is kept forever
Used in the project
To store the token
- encapsulation
localStorage
API, exposed to provide operation methods
Utils.js adds several operation methods
/ / save
export const saveAccessToken = (token) = > {
localStorage.setItem(MOOSE_REACT_LEARN_ACCESS_TOKEN, token);
};
/ / to get
export const getAccessToken = () = > {
return localStorage.getItem(MOOSE_REACT_LEARN_ACCESS_TOKEN) || 'MOOSE_REACT_LEARN';
};
/ / remove
export const removeAccessToken = () = > {
localStorage.removeItem(MOOSE_REACT_LEARN_ACCESS_TOKEN);
};
// Encapsulate the parameters in the request header
export const getAuthorization = () = > {
let accessToken = getAccessToken();
returnisEmpty(accessToken) ? {}, {Authorization: `Bearer ${getAccessToken()}`}; };// Redirect to the login interface for login
export const redirectLogin = () = > {
const { redirect } = getPageQuery(); // Note: There may be security issues, please note
if (window.location.pathname ! = ='/login' && !redirect) {
removeAccessToken();
history.replace({
pathname: '/login'.search: stringify({
redirect: window.location.href, }), }); }};Copy the code
- After the login is complete, use the
localStorage
Save the AccessToken returned by the interface
Example Modify the login interface logic
import { saveAccessToken } from '@/utils/utils'; . *login({ payload }, { call, put }) {
// Submit the processed parameters
const response = yield call(postAccountLogin, params);
yield put({
type: 'changeLoginStatus'.payload: response,
}); // Login successfully
if (response.code === 200) {
// Add this line
saveAccessToken(response.data);
const urlParams = new URL(window.location.href); .Copy the code
- Put accessToken in the request header and send it on every request
Modify request.js package, add umi-Request request interceptor
request.interceptors.request.use(
(url, options) = > {
// console.log('request.interceptors.request', options);
// Some other properties can be set
return {
url,
options: { ...options, headers: {... options.headers, ... getAuthorization() } }, }; }, {global: true});Copy the code
Modify SecurityLayout so that the userId is the same as the returned field
Modify AvatarDropdown,userName and return to the same field
The refresh token
OAuth2.0 password mode authorization, which returns access_token and refresh_token
The server interface only returns access_token after login, refresh_token is saved to the server (redis).
The expiration time of refresh_token should be set longer than that of access_token. Ensure that refresh_token can be used to request access_token
When the Access_Token is invalid, the front end requests refresh_token using the last Access_Token, returns the access_token, and requests again
reference
- Spring Boot 2.x Quick Start
- SpringBoot OAuth2.0 Authentication and authorization (password mode)
- SpringBoot OAuth2.0 encapsulates the login and refresh token interface
The API return code needs to be agreed with the front end
- Java service interface definition
code
/** * token */
TOKEN_IS_EMPTY(-10101."token must not be null"),
TOKEN_VALIDATE_FAIL(-10102."token check fail"),
TOKEN_INVALID(-10103."invalid access token"),
REFRESH_TOKEN_NOT_EXIST(-10104."refresh token not exist"),
ACCESS_TOKEN_IS_EMPTY(-10105."access token is empty"),
Copy the code
- Invoke the refresh token interface
services/token.js
import { getAccessToken } from '@/utils/utils';
import request from '@/utils/request';
export async function postRefreshToken() {
return request('/api/v1/token/refresh', {
method: 'POST'.requestType: 'form'.data: {
accessToken: getAccessToken(),
},
});
}
Copy the code
- Modify the
request.js
// Retry function
const retry = (response, options) = > {
return request(response.url, options);
};
request.interceptors.response.use(async (response, options) => {
// Copy the last request
const { status } = await response.clone();
if (status === 401) {
const { code: normalCode } = await response.clone().json();
if (normalCode === 401) {
redirectLogin();
return;
}
// -10103 indicates that the request token is invalid
if (normalCode === -10103) {
const { data, code: refreshCode } = await postRefreshToken();
// Return code when the refresh token is obtained
if (refreshCode === -10101 || refreshCode === -10102 || refreshCode === -10104) {
redirectLogin();
return;
}
saveAccessToken(data);
returnretry(response, options); }}return response;
});
Copy the code
When the accessToken time expires, refreshToken can be used to obtain accessToken again to continue the request