前後端分離-根據程式碼講解思路
1.前面寫過前後端分離相關文章
第一篇-為什麼要前後端分離 https://blog.csdn.net/m0_37499059/article/details/82082534
第二篇-感受一下前後端分離 https://blog.csdn.net/m0_37499059/article/details/82082825
原始碼下載: https://github.com/chenxingxing6/cxxfast
2.根據程式碼講解思路
使用者登入時,生成一個token,並給token設一個過期時間,儲存在資料庫裡(redis裡)。每次請求api時都帶上該token,然後對token進行校驗,是不是該使用者的,並且時間有沒有過期。這裡的token最後是放在請求頭裡面,然後設定全域性範圍起作用,不需要每次還關心要自己傳token.
2.1 token什麼時候生成(使用者授權認證成功後)
token用什麼演算法生成,看自己怎麼實現了
@Override
public R createToken(long userId) {
//生成一個token
String token = TokenGenerator.generateValue();
//當前時間
Date now = new Date();
//過期時間
Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
//判斷是否生成過token
SysUserToken tokenEntity = sysUserTokenDao.selectById(userId);
if(tokenEntity == null){
tokenEntity = new SysUserToken();
tokenEntity.setUserId(userId);
tokenEntity.setToken(token);
tokenEntity.setUpdateTime(now);
tokenEntity.setExpireTime(expireTime);
//儲存token
sysUserTokenDao.insert(tokenEntity);
}else{
tokenEntity.setToken(token);
tokenEntity.setUpdateTime(now);
tokenEntity.setExpireTime(expireTime);
//更新token
sysUserTokenDao.updateById(tokenEntity);
}
R r = R.ok().put("token", token).put("expire", EXPIRE);
return r;
}
生成token
package cn.jeefast.common.oauth2;
import java.security.MessageDigest;
import java.util.UUID;
import cn.jeefast.common.exception.RRException;
/**
* 生成token
*/
public class TokenGenerator {
public static String generateValue() {
return generateValue(UUID.randomUUID().toString());
}
private static final char[] hexCode = "0123456789abcdef".toCharArray();
public static String toHexString(byte[] data) {
if(data == null) {
return null;
}
StringBuilder r = new StringBuilder(data.length*2);
for ( byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
public static String generateValue(String param) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(param.getBytes());
byte[] messageDigest = algorithm.digest();
return toHexString(messageDigest);
} catch (Exception e) {
throw new RRException("生成Token失敗", e);
}
}
}
2.2 前端登入接收到返回的訊息和token,然後把token保持的本地(localstorage 儲存物件)
2.3然後設定全域性js,獲取token,並設定ajax請求是head都統一帶上token
common.js
//請求字首
var baseURL = "/project/";
//登入token
var token = localStorage.getItem("token");
if(token == 'null'){
parent.location.href = baseURL + 'login.html';
}
//jquery全域性配置
$.ajaxSetup({
dataType: "json",
cache: false,
headers: {
"token": token
},
complete: function(xhr) {
//token過期,則跳轉到登入頁面
if(xhr.responseJSON.code == 401){
parent.location.href = baseURL + 'login.html';
}
}
});
//jqgrid全域性配置
$.extend($.jgrid.defaults, {
ajaxGridOptions : {
headers: {
"token": token
}
}
});
2.4 退出登入操作,清除token
logout: function () {
//刪除本地token
localStorage.removeItem("token");
//跳轉到登入頁面
location.href = baseURL + 'login.html';
}
2.5 Java對api進行攔截,除了不需要許可權的,去校驗token
第一種方式:用了shiro框架
第二種方式:寫一個攔截器,對token進行校驗
這裡我們自己定義一個註解,如果不要授權的api,就加上改註解
攔截器實現
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Autowired
private TbTokenService tokenService;
public static final String USER_KEY = "userId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
AuthIgnore annotation;
if(handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
}else{
return true;
}
//如果有@IgnoreAuth註解,則不驗證token
if(annotation != null){
return true;
}
//從header中獲取token
String token = request.getHeader("token");
//如果header中不存在token,則從引數中獲取token
if(StringUtils.isBlank(token)){
token = request.getParameter("token");
}
//token為空
if(StringUtils.isBlank(token)){
throw new RRException("token不能為空");
}
//查詢token資訊
TbToken tokenEntity = tokenService.queryByToken(token);
if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
throw new RRException("token失效,請重新登入");
}
//設定userId到request裡,後續根據userId,獲取使用者資訊
request.setAttribute(USER_KEY, tokenEntity.getUserId());
return true;
}
}
註解:
import java.lang.annotation.*;
/**
* api介面,忽略Token驗證
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthIgnore {
}
總結
其實也很簡單嘛,就後臺提供restful介面,我前端去請求,然後解析json,絢爛我們的頁面。但是這個介面肯定要有許可權吧,不能讓每個人都調的到,所以我們要進行認證,那我們根據使用者資訊,生成一個有過期時間的唯一的token,每次請求都帶上,後臺對token統一進行校驗,如果是正確的進放行。
相關文章
- 前後端分離那些事後端
- 再談前後端分離後端
- 淺談前後端分離後端
- 前後端分離——使用OSS後端
- 前後端分離整合SpringSecurity後端SpringGse
- 前後端分離解決跨域問題後端跨域
- 原始碼編譯,Apache DolphinScheduler前後端分離部署解決方案原始碼編譯Apache後端
- vue前後端分離修改webpackVue後端Web
- 前後端分離——資料mock後端Mock
- 前後端分離Ajax入門後端
- ???前後端分離模式的思考???後端模式
- 前後端分離使用 Token 登入解決方案後端
- 前後端分離後模組開發後端
- 前後端分離的優缺點後端
- Laravel 前後端分離 csrf 防護Laravel後端
- spring shiro+cas 前後端分離Spring後端
- 實現前後端分離的心得後端
- 前後端分離之Ajax入門後端
- 從部署上做到前後端分離後端
- Flask前後端分離專案案例Flask後端
- 簡單的前後端分離 Cas後端
- Cloudera Manager 前後端分離部署方法Cloud後端
- vue專案實踐-前後端分離關於許可權的思路Vue後端
- 解決 Laravel 5.8 前後端分離跨域問題Laravel後端跨域
- 你不得不瞭解的前後端分離原理!後端
- node-vue前後端分離記錄Vue後端
- axios前後端分離下載檔案iOS後端
- 用jQuery怎麼做到前後端分離jQuery後端
- 前後端分離前端模擬資料後端前端
- Web前後端:如何分離,如何解耦?Web後端解耦
- jQuery 前後端分離專案總結jQuery後端
- 前後端分離開發腳手架後端
- 前後端分離開發部署模式【轉】後端模式
- 前後端分離的好處有哪些?後端
- 前後端分離技術路線圖後端
- 前後端分離之更好的mock你的後端api後端MockAPI
- 利用1panel部署前後端分離專案 Java程式碼打包 前端打包後端Java前端
- ruoyi vue 前後端分離版本 打包分離jar包至libVue後端JAR