当前位置: 首页 > news >正文

建设一个百度百科类网站公司电脑做网站

建设一个百度百科类网站,公司电脑做网站,济南做网站xywlcn,南通网站优化找哪家文章目录 JWT实现单点登录JWT 简介存在问题及解决方案登录流程后端程序实现前端保存Tokenstore存放信息的缺点及解决 校验流程:为gateway增加登录校验拦截器 另一种单点登录方法:Token+Redis实现单点登录 JWT实现单点登录 登录流程&#xff…

文章目录

  • JWT实现单点登录
    • JWT 简介
    • 存在问题及解决方案
    • 登录流程
      • 后端程序实现
      • 前端保存Token
      • store存放信息的缺点及解决
    • 校验流程:为gateway增加登录校验拦截器
  • 另一种单点登录方法:Token+Redis实现单点登录

JWT实现单点登录

  • 登录流程:
    校验用户名密码->生成随机JWT Token->返回给前端。之后前端发请求携带该Token就能验证是哪个用户了。
  • 校验流程:
    从前端请求的header获取JWT Token->根据工具包校验JWT Token->校验成功或失败

JWT 简介

结构
Header 头部信息,主要声明了JWT的签名算法等信息
Payload 载荷信息,主要承载了各种声明并传递明文数据
Signature 签名,拥有该部分的JWT被称为JWS,也就是签了名的JWT,用于校验数据
整体结构是:

header.payload.signature

参考文档:https://doc.hutool.cn/pages/jwt/

存在问题及解决方案

    1. token被解密:如工具包被获取。可通过增加“盐值”来解决。
    1. token被拿到第三方使用:如被包装到第三方使用(ChatGPT工具),可以通过限流来解决。

登录流程

后端程序实现

封装hutool工具类:

public class JwtUtil {private static final Logger LOG = LoggerFactory.getLogger(JwtUtil.class);/*** 盐值很重要,不能泄漏,且每个项目都应该不一样,可以放到配置文件中*/private static final String key = "xxx";public static String createToken(Long id, String mobile) {LOG.info("开始生成JWT token,id:{},mobile:{}", id, mobile);GlobalBouncyCastleProvider.setUseBouncyCastle(false);DateTime now = DateTime.now();DateTime expTime = now.offsetNew(DateField.HOUR, 24);
//        DateTime expTime = now.offsetNew(DateField.SECOND, 10);Map<String, Object> payload = new HashMap<>();// 签发时间payload.put(JWTPayload.ISSUED_AT, now);// 过期时间payload.put(JWTPayload.EXPIRES_AT, expTime);// 生效时间payload.put(JWTPayload.NOT_BEFORE, now);// 内容payload.put("id", id);payload.put("mobile", mobile);String token = JWTUtil.createToken(payload, key.getBytes());LOG.info("生成JWT token:{}", token);return token;}public static boolean validate(String token) {LOG.info("开始JWT token校验,token:{}", token);GlobalBouncyCastleProvider.setUseBouncyCastle(false);JWT jwt = JWTUtil.parseToken(token).setKey(key.getBytes());// validate包含了verifyboolean validate = jwt.validate(0);LOG.info("JWT token校验结果:{}", validate);return validate;}public static JSONObject getJSONObject(String token) {GlobalBouncyCastleProvider.setUseBouncyCastle(false);JWT jwt = JWTUtil.parseToken(token).setKey(key.getBytes());JSONObject payloads = jwt.getPayloads();payloads.remove(JWTPayload.ISSUED_AT);payloads.remove(JWTPayload.EXPIRES_AT);payloads.remove(JWTPayload.NOT_BEFORE);LOG.info("根据token获取原始内容:{}", payloads);return payloads;}public static void main(String[] args) {createToken(1L, "123");String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3MzY0ODczMDQsIm1vYmlsZSI6IjEyMyIsImlkIjoxLCJleHAiOjE3MzY1NzM3MDQsImlhdCI6MTczNjQ4NzMwNH0.Bui7guCvPEF557eqxRLwmt5tO-W-3oVLnn37H4qOVfA";validate(token);getJSONObject(token);}
}

后端定义登录业务:

    public MemberLoginResp login(MemberLoginReq memberLoginReq){String mobile = memberLoginReq.getMobile();String code = memberLoginReq.getCode();Member memberDB = selectByMobile(mobile);if (ObjectUtil.isEmpty(memberDB)){throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_NOT_EXIST);}if(!code.equals("8888")){throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_CODE_ERROR);}MemberLoginResp memberLoginResp = new MemberLoginResp();memberLoginResp.setId(memberDB.getId());memberLoginResp.setMobile(mobile);String token = JwtUtil.createToken(memberDB.getId(), memberDB.getMobile());memberLoginResp.setToken(token);return memberLoginResp;}

通过调用封装的JwtUtil生成token并返回前端

在这里插入图片描述

成功返回Token结果

前端保存Token

Vuex全局保存Token到store中

import { createStore } from 'vuex'const MEMBER = "MEMBER";export default createStore({state: {member: {}},getters: {},mutations: {setMember (state, _member) {state.member = _member;}},actions: {},modules: {}
})
    const login = () => {axios.post("/member/member/login", loginForm).then((response) => {let data = response.data;if (data.success) {notification.success({ description: '登录成功!' });// 登录成功,跳到控台主页router.push("/welcome");store.commit("setMember", data.content);} else {notification.error({ description: data.message });}})};

store存放信息的缺点及解决

store存放用户信息后,如果刷新页面,那么信息也会消失!
store可以理解为缓存,一旦重新加载,则缓存全都没了。

解决方法:

  • step1. 新增session-storage.js,封装会话缓存sessionStorage
// 所有的session key都在这里统一定义,可以避免多个功能使用同一个key
SESSION_ORDER = "SESSION_ORDER";
SESSION_TICKET_PARAMS = "SESSION_TICKET_PARAMS";SessionStorage = {get: function (key) {var v = sessionStorage.getItem(key);if (v && typeof(v) !== "undefined" && v !== "undefined") {return JSON.parse(v);}},set: function (key, data) {sessionStorage.setItem(key, JSON.stringify(data));},remove: function (key) {sessionStorage.removeItem(key);},clearAll: function () {sessionStorage.clear();}
};
  • step2. 在index.html中引入该js
<!DOCTYPE html>
<html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><link rel="icon" href="<%= BASE_URL %>favicon.ico"><!-- 引入js --><script src="<%= BASE_URL %>js/session-storage.js"></script><title><%= htmlWebpackPlugin.options.title %></title></head><body><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><!-- built files will be auto injected --></body>
</html>
  • step3. 修改store的index.js
const MEMBER = "MEMBER";export default createStore({state: {member: window.SessionStorage.get(MEMBER) || {} # 读取},getters: {},mutations: {setMember (state, _member) {state.member = _member;window.SessionStorage.set(MEMBER, _member); # 设置}},

不再是把member定义为{},而是首先在缓存中获取,如果没有则设置为{}。同时避免空指针
同时在用户登录后设置MEMBER缓存

校验流程:为gateway增加登录校验拦截器

  • 添加依赖
            <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version></dependency>
  • 拦截器类
@Component
public class LoginMemberFilter implements Ordered, GlobalFilter {private static final Logger LOG = LoggerFactory.getLogger(LoginMemberFilter.class);@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String path = exchange.getRequest().getURI().getPath();// 排除不需要拦截的请求if (path.contains("/admin")|| path.contains("/redis")|| path.contains("/test")|| path.contains("/member/member/login")|| path.contains("/member/member/send-code")) {LOG.info("不需要登录验证:{}", path);return chain.filter(exchange);} else {LOG.info("需要登录验证:{}", path);}// 获取header的token参数String token = exchange.getRequest().getHeaders().getFirst("token");LOG.info("会员登录验证开始,token:{}", token);if (token == null || token.isEmpty()) {LOG.info( "token为空,请求被拦截" );exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}// 校验token是否有效,包括token是否被改过,是否过期boolean validate = JwtUtil.validate(token);if (validate) {LOG.info("token有效,放行该请求");return chain.filter(exchange);} else {LOG.warn( "token无效,请求被拦截" );exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}}/*** 优先级设置  值越小  优先级越高** @return*/@Overridepublic int getOrder() {return 0;}
}
  • 测试结果:
  1. 直接调用不需要验证登录的接口
@RestController
public class TestController {@GetMapping("/test")public String test(){return "test";}}

在这里插入图片描述

  1. 调用需要登录的接口方法(未登录)
    在这里插入图片描述

同时服务器端没有打印,表示请求已被拦截

  1. 调用login登陆后再次执行上述请求
    login打印日志:
    在这里插入图片描述
    调用请求打印日志:
    在这里插入图片描述

可见成功校验token,并读取登录用户信息,通过校验

另一种单点登录方法:Token+Redis实现单点登录

  • 登录流程:
    校验用户名密码->生成随机Token->将Token存放到Redis,并返回给前端。
    之后前端发请求携带该Token就能验证是哪个用户了。
  • 校验流程:
    从前端请求的header获取Token->根据Token到Redis获取用户数据->若有数据则登录校验通过,否则失败
http://www.yayakq.cn/news/839600/

相关文章:

  • 做网站一般按什么报价网站怎样制作吸引人
  • 平顶山城市住房城乡建筑网站做淘宝的网站有哪些内容
  • 网站开发公司名称wordpress网站二次开发
  • 山西百度公司做网站的长治网络推广公司
  • 天津做艺术品的网站企业oa
  • 怎样制作表白网站网站开发公司徐州
  • 徐州专业制作网站文山知名网站建设联系电话
  • 在搜狐快站上做网站怎么跳转wordpress大数据
  • wordpress 知名网站网站营销方案
  • access 数据库做网站崇信县门户网站
  • html5 网站源码陕西省住建厅网站官网
  • 茂名网站建设方案推广影视网站建设需要学什么
  • 口碑好网站建设多少钱横琴网站建设
  • 浙江网站建设流程网页制作企业网站作业
  • 建电商网站要多少钱做网站赚钱
  • 网站关键词突然搜不到浅谈电子商务网站建设与规划
  • 专业的大良网站建设有没有兼职做网站的
  • 湖南建筑公司网站佛山专业做淘宝网站
  • 网站添加关键字cpa怎么做网站
  • 大型网站建设完全教程有做阿里网站的吗
  • 网站开发的网课在哪.net做网站用什么框架
  • 网站开发的实训报告如何申请网页域名
  • 网站建设 seo sem人力资源公司是中介公司吗
  • 域名查询网站入口网站等保测评怎么做
  • 建网站安全校园网络及网站建设
  • 网站退出率友博国际个人中心登录
  • 杭州模板建站代理大型网站和小企业站优化思路
  • 上海网站建设公ui设计案例网站
  • 电商网站报价传奇怎么建设自己的网站
  • 优享微信网站建设wordpress wampsever