用户修改了信息jwt服务器怎么识别,jwt验证登录信息
為什么要告別session?有這樣一個場景,系統(tǒng)的數(shù)據(jù)量達(dá)到千萬級,需要幾臺服務(wù)器部署,當(dāng)一個用戶在其中一臺服務(wù)器登錄后,用session保存其登錄信息,其他服務(wù)器怎么知道該用戶登錄了?(單點(diǎn)登錄),當(dāng)然解決辦法有,可以用spring-session。如果該系統(tǒng)同時為移動端服務(wù)呢?移動端通過url向后臺要數(shù)據(jù),如果用session,通過sessionId識別用戶,萬一sessionId被截獲了,別人可以利用sessionId向后臺要數(shù)據(jù),就有安全隱患了。所以有必要跟session說拜拜了。服務(wù)端不需要存儲任何用戶的信息,用戶的驗(yàn)證應(yīng)該放在客戶端,jwt就是這種方式!
什么是jwt?
這里以java的ssm框架為例,集成jwt。
1.pom.xml 導(dǎo)入jwt的包
com.auth0
java-jwt
2.2.0
2.編寫jwt的工具類,有加密解密功能就好
import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.internal.com.fasterxml.jackson.databind.ObjectMapper;
?
import java.util.HashMap;
import java.util.Map;
?
public class JWT {
private static final String SECRET = "XX#$%()(#*!()!KL<>?N<:>
?
private static final String EXP = "exp";
?
private static final String PAYLOAD = "payload";
?
//加密,傳入一個對象和有效期
public static String sign(T object, long maxAge) {
try {
final JWTSigner signer = new JWTSigner(SECRET);
final Map claims = new HashMap();
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(object);
claims.put(PAYLOAD, jsonString);
claims.put(EXP, System.currentTimeMillis() + maxAge);
return signer.sign(claims);
} catch(Exception e) {
return null;
}
}
?
//解密,傳入一個加密后的token字符串和解密后的類型
public static T unsign(String jwt, Class classT) {
final JWTVerifier verifier = new JWTVerifier(SECRET);
try {
final Map claims= verifier.verify(jwt);
if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
long exp = (Long)claims.get(EXP);
long currentTimeMillis = System.currentTimeMillis();
if (exp > currentTimeMillis) {
String json = (String)claims.get(PAYLOAD);
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, classT);
}
}
return null;
} catch (Exception e) {
return null;
}
}
?
}
3.jwt有了,ssm要如何去利用,用戶驗(yàn)證的第一步是登錄,登錄時根據(jù)用戶傳來的username和password到數(shù)據(jù)庫驗(yàn)證身份,如果合法,便給該用戶jwt加密生成token
//處理登錄
@RequestMapping(value="login", produces = "application/json; charset=utf-8")
public @ResponseBody ResponseData login(HttpServletRequest request, @RequestParam( "email") String email,
@RequestParam("password") String password) {
Login login = new Login();
login.setEmail(email);
login.setPassword(password);
ResponseData responseData = ResponseData.ok();
//先到數(shù)據(jù)庫驗(yàn)證
Integer loginId = userService.checkLogin(login);
if(null != loginId) {
User user = userService.getUserByLoginId(loginId);
login.setId(loginId);
//給用戶jwt加密生成token
String token = JWT.sign(login, 60L* 1000L* 30L);
//封裝成對象返回給客戶端
responseData.putDataValue("loginId", login.getId());
responseData.putDataValue("token", token);
responseData.putDataValue("user", user);
}
else{
responseData = ResponseData.customerError();
}
return responseData;
}
4.在用戶登錄時,把loginId和token返回給前臺,以后用戶每次請求時,都得帶上這兩個參數(shù),后臺拿到token后解密出loginId,與用戶傳遞過來的loginId比較,如果相同,則說明用戶身份合法。因?yàn)槭敲總€登錄過后的每個請求,這里用springmvc的攔截器做
5.攔截器代碼
import java.io.PrintWriter;
?
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
?
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
?
import com.alibaba.fastjson.JSONObject;
import com.xforce.charles.model.Admin;
import com.xforce.charles.model.Login;
import com.xforce.charles.util.JWT;
import com.xforce.charles.util.ResponseData;
?
public class TokenInterceptor implements HandlerInterceptor{
?
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception arg3)
throws Exception {
}
?
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView model) throws Exception {
}
?
//攔截每個請求
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
response.setCharacterEncoding("utf-8");
String token = request.getParameter("token");
ResponseData responseData = ResponseData.ok();
//token不存在
if(null != token) {
Login login = JWT.unsign(token, Login.class);
String loginId = request.getParameter("loginId");
//解密token后的loginId與用戶傳來的loginId不一致,一般都是token過期
if(null != loginId && null != login) {
if(Integer.parseInt(loginId) == login.getId()) {
return true;
}
else{
responseData = ResponseData.forbidden();
responseMessage(response, response.getWriter(), responseData);
return false;
}
}
else
{
responseData = ResponseData.forbidden();
responseMessage(response, response.getWriter(), responseData);
return false;
}
}
else
{
responseData = ResponseData.forbidden();
responseMessage(response, response.getWriter(), responseData);
return false;
}
}
?
//請求不通過,返回錯誤信息給客戶端
private void responseMessage(HttpServletResponse response, PrintWriter out, ResponseData responseData) {
responseData = ResponseData.forbidden();
response.setContentType("application/json; charset=utf-8");
String json = JSONObject.toJSONString(responseData);
out.print(json);
out.flush();
out.close();
}
?
}
6.注意點(diǎn):用@ResponseBody返回json數(shù)據(jù)時,有時會有亂碼,需要在springmvc的配置文件里面加以下配置(spring4以上)
7.最后分享一個類,用于返回給客戶端的萬能類,我覺得它可以滿足一般的接口
import java.util.HashMap;
import java.util.Map;
?
public class ResponseData {
?
private final String message;
private final int code;
private final Map data = new HashMap();
?
public String getMessage() {
return message;
}
?
public int getCode() {
return code;
}
?
public Map getData() {
return data;
}
?
public ResponseData putDataValue(String key, Object value) {
data.put(key, value);
return this;
}
?
private ResponseData(int code, String message) {
this.code = code;
this.message = message;
}
?
public static ResponseData ok() {
return new ResponseData(200, "Ok");
}
?
public static ResponseData notFound() {
return new ResponseData(404, "Not Found");
}
?
public static ResponseData badRequest() {
return new ResponseData(400, "Bad Request");
}
?
public static ResponseData forbidden() {
return new ResponseData(403, "Forbidden");
}
?
public static ResponseData unauthorized() {
return new ResponseData(401, "unauthorized");
}
?
public static ResponseData serverInternalError() {
return new ResponseData(500, "Server Internal Error");
}
?
public static ResponseData customerError() {
return new ResponseData(1001, "customer Error");
}
}
解決:使用ajax驗(yàn)證登錄信息返回前端頁面時,當(dāng)前整個頁面刷新。
源代碼如下: function loginform(){ $.ajax({ url:"loginValidate.do", type:'post', data:{"nam ...
golang學(xué)習(xí)筆記10 beego api 用jwt驗(yàn)證auth2 token 獲取解碼信息
golang學(xué)習(xí)筆記10 beego api 用jwt驗(yàn)證auth2 token?獲取解碼信息 Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放 ...
Python 解密JWT驗(yàn)證蘋果登錄
驗(yàn)證蘋果登錄,官方提供兩種驗(yàn)證方法,一種是token,另一個種是code.這里使用的是token 登錄流程: 蘋果客戶端調(diào)用蘋果API,獲取到用戶的信息,包括: user_id 昵稱 identity ...
spring boot:spring security整合jwt實(shí)現(xiàn)登錄和權(quán)限驗(yàn)證(spring boot 2.3.3)
一,為什么使用jwt? 1,什么是jwt? Json Web Token, 它是JSON風(fēng)格的輕量級的授權(quán)和身份認(rèn)證規(guī)范, 可以實(shí)現(xiàn)無狀態(tài).分布式的Web應(yīng)用授權(quán) 2,jwt的官網(wǎng): https:// ...
Spring 筆記 -06- 從 MySQL 建庫到 登錄驗(yàn)證數(shù)據(jù)庫信息(maven)
Spring 筆記 -06- 從 MySQL 建庫到 登錄驗(yàn)證數(shù)據(jù)庫信息(maven) 本篇和 Spring 沒有什么關(guān)系,只是學(xué)習(xí) Spring,必備一些知識,所以放在這里了. 本篇內(nèi)容: (1)M ...
spring集成jwt驗(yàn)證方式,token驗(yàn)證
為什么要告別session?有這樣一個場景,系統(tǒng)的數(shù)據(jù)量達(dá)到千萬級,需要幾臺服務(wù)器部署,當(dāng)一個用戶在其中一臺服務(wù)器登錄后,用session保存其登錄信息,其他服務(wù)器怎么知道該用戶登錄了?(單點(diǎn)登錄), ...
webapi中使用token驗(yàn)證(JWT驗(yàn)證)
本文介紹如何在webapi中使用JWT驗(yàn)證 準(zhǔn)備 安裝JWT安裝包 System.IdentityModel.Tokens.Jwt 你的前端api登錄請求的方法,參考 axios.get(" ...
django--通過jwt獲取用戶信息的兩種方式
HTTP請求是無狀態(tài)的,我們通常會使用cookie或session對其進(jìn)行狀態(tài)保持,cookie存儲在客戶端,容易被用戶誤刪,安全性不高,session存儲在服務(wù)端,在服務(wù)器集群情況下需要解決sess ...
隨機(jī)推薦
[Android Pro] AES加密
reference to :http://blog.csdn.net/wfung_kwok/article/details/7766427 package com.secufity.aes; impo ...
UITableViewCell重用的問題
UITableView中有兩種重用Cell的方法: -?(id)dequeueReusableCellWithIdentifier:(NSString?*)identifier; -?(id)dequ ...
關(guān)于yum與源碼安裝的LAMP或LNMP網(wǎng)頁直接顯示空白頁的問題?
學(xué)習(xí)LAMP.LNMP時,遇到很奇怪的問題就是:搭建完LAMP或LNMP環(huán)境后安裝PHPweb程序時,Discuz和Wordpress打不開安裝向?qū)?直接顯示空白頁(PHPWind9.0除外),沒有任 ...
Qt入門學(xué)習(xí)——Qt 5 幫助文檔的使用
Qt入門學(xué)習(xí)——Qt 5 幫助文檔的使用 學(xué)習(xí)圖形界面開發(fā),肯定離不開幫助文檔的使用,因?yàn)樗幌?C 語言那樣就那么幾個函數(shù)接口,圖形接口的接口可以用海量來形容,常用的我們可能能記住,其它的真的沒有必 ...
2D-2D:對極幾何 基礎(chǔ)矩陣F 本質(zhì)矩陣E 單應(yīng)矩陣H
對極約束 \[ \boldsymbol{x}_{2}^{T} \boldsymbol{F} \boldsymbol{x}_{1}=\boldsymbol{0} \quad \hat{\boldsymb ...
Android:進(jìn)程優(yōu)先級
進(jìn)程優(yōu)先級 優(yōu)先級 服務(wù) 說明 高優(yōu)先級 前臺進(jìn)程 ①該進(jìn)程包含正在與用戶進(jìn)行交互的界面組件,比如一個Activity. ②進(jìn)程服務(wù)被Activity調(diào)用,而且這個Activity正在與用戶進(jìn)行交互 ...
zabbix監(jiān)控短信息接口是否正常
1.創(chuàng)建Web scenarios 2.創(chuàng)建zabbix觸發(fā)器name:short_message send status is not 100 Expression:{u04zbx01.yaya.c ...
mysql sleep進(jìn)程 過多
如果你沒有修改過MySQL的配置,缺省情況下,wait_timeout的初始值是28800. wait_timeout過大有弊端,其體現(xiàn)就是MySQL里大量的SLEEP進(jìn)程無法及時釋放,拖累系統(tǒng)性能, ...
【dijkstra】【次短路】【fread】hdu6181 Two Paths
題意:給你一張簡單無向圖,問你1到n的次短路.注意,可以不是簡單路徑. 存?zhèn)€次短路板子,原理還是挺簡單,直接看代碼吧.然后這份代碼還是個fread的示例用法. #include
總結(jié)
以上是生活随笔為你收集整理的用户修改了信息jwt服务器怎么识别,jwt验证登录信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java入职华为,通过这9个Java面试
- 下一篇: java矩阵类_151-矩阵类