用户修改了信息jwt服务器怎么识别,jwt验证登录信息

为什么要告别session?有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在其中一台服务器登录后,用session保存其登录信息,其他服务器怎么知道该用户登录了?(单点登录),当然解决办法有,可以用spring-session。如果该系统同时为移动端服务呢?移动端通过url向后台要数据,如果用session,通过sessionId识别用户,万一sessionId被截获了,别人可以利用sessionId向后台要数据,就有安全隐患了。所以有必要跟session说拜拜了。服务端不需要存储任何用户的信息,用户的验证应该放在客户端,jwt就是这种方式!

什么是jwt?

b76d9af75f6666f86d869d742893091c.png

这里以java的ssm框架为例,集成jwt。

1.pom.xml 导入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要如何去利用,用户验证的第一步是登录,登录时根据用户传来的username和password到数据库验证身份,如果合法,便给该用户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();

//先到数据库验证

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返回给前台,以后用户每次请求时,都得带上这两个参数,后台拿到token后解密出loginId,与用户传递过来的loginId比较,如果相同,则说明用户身份合法。因为是每个登录过后的每个请求,这里用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.注意点:用@ResponseBody返回json数据时,有时会有乱码,需要在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验证登录信息返回前端页面时,当前整个页面刷新。

源代码如下: function loginform(){ $.ajax({ url:"loginValidate.do", type:'post', data:{"nam ...

golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息

golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...

Python 解密JWT验证苹果登录

验证苹果登录,官方提供两种验证方法,一种是token,另一个种是code.这里使用的是token 登录流程: 苹果客户端调用苹果API,获取到用户的信息,包括: user_id 昵称 identity ...

spring boot&colon;spring security整合jwt实现登录和权限验证&lpar;spring boot 2&period;3&period;3&rpar;

一,为什么使用jwt? 1,什么是jwt? Json Web Token, 它是JSON风格的轻量级的授权和身份认证规范, 可以实现无状态.分布式的Web应用授权 2,jwt的官网: https:// ...

Spring 笔记 -06- 从 MySQL 建库到 登录验证数据库信息(maven)

Spring 笔记 -06- 从 MySQL 建库到 登录验证数据库信息(maven) 本篇和 Spring 没有什么关系,只是学习 Spring,必备一些知识,所以放在这里了. 本篇内容: (1)M ...

spring集成jwt验证方式,token验证

为什么要告别session?有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在其中一台服务器登录后,用session保存其登录信息,其他服务器怎么知道该用户登录了?(单点登录), ...

webapi中使用token验证(JWT验证)

本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get(" ...

django--通过jwt获取用户信息的两种方式

HTTP请求是无状态的,我们通常会使用cookie或session对其进行状态保持,cookie存储在客户端,容易被用户误删,安全性不高,session存储在服务端,在服务器集群情况下需要解决sess ...

随机推荐

&lbrack;Android Pro&rsqb; 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 ...

关于yum与源码安装的LAMP或LNMP网页直接显示空白页的问题?

学习LAMP.LNMP时,遇到很奇怪的问题就是:搭建完LAMP或LNMP环境后安装PHPweb程序时,Discuz和Wordpress打不开安装向导,直接显示空白页(PHPWind9.0除外),没有任 ...

Qt入门学习——Qt 5 帮助文档的使用

Qt入门学习——Qt 5 帮助文档的使用 学习图形界面开发,肯定离不开帮助文档的使用,因为它不像 C 语言那样就那么几个函数接口,图形接口的接口可以用海量来形容,常用的我们可能能记住,其它的真的没有必 ...

2D-2D&colon;对极几何 基础矩阵F 本质矩阵E 单应矩阵H

对极约束 \[ \boldsymbol{x}_{2}^{T} \boldsymbol{F} \boldsymbol{x}_{1}=\boldsymbol{0} \quad \hat{\boldsymb ...

Android:进程优先级

进程优先级 优先级 服务 说明 高优先级 前台进程 ①该进程包含正在与用户进行交互的界面组件,比如一个Activity. ②进程服务被Activity调用,而且这个Activity正在与用户进行交互 ...

zabbix监控短信息接口是否正常

1.创建Web scenarios 2.创建zabbix触发器name:short_message send status is not 100 Expression:{u04zbx01.yaya.c ...

mysql sleep进程 过多

如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800. wait_timeout过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统性能, ...

【dijkstra】【次短路】【fread】hdu6181 Two Paths

题意:给你一张简单无向图,问你1到n的次短路.注意,可以不是简单路径. 存个次短路板子,原理还是挺简单,直接看代码吧.然后这份代码还是个fread的示例用法. #include

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值