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

新乡做网站公兰州网络推广制度

新乡做网站公,兰州网络推广制度,安徽城乡建设厅网站焊工证查询,建设房屋出租网站文章目录 前言一、双Token方案介绍1. 令牌类型与功能2.双Token方案的优点3.实现流程 二、具体实现1.后端实现1.1 jwt工具类1.2 响应工具类1.3 实体类1.4 过滤器1.5 controller1.6 启动类 2、前端实现2.1 登录页面2.2 index页面2.3 请求拦截器和响应拦截器 效果展示 前言 更多j… 文章目录 前言一、双Token方案介绍1. 令牌类型与功能2.双Token方案的优点3.实现流程 二、具体实现1.后端实现1.1 jwt工具类1.2 响应工具类1.3 实体类1.4 过滤器1.5 controller1.6 启动类 2、前端实现2.1 登录页面2.2 index页面2.3 请求拦截器和响应拦截器 效果展示 前言 更多jwt相关文章 jwt理论介绍 springbootvue项目中使用jwt实现登录认证 本篇文章的代码是在springbootvue项目中使用jwt实现登录认证的基础上实现的Token自动续期的功能。 一、双Token方案介绍 双token解决方案是一种用于增强用户登录安全性和提升用户体验的认证机制。它主要涉及两个令牌访问令牌accessToken和刷新令牌refreshToken。以下是对双token解决方案的详细介绍 1. 令牌类型与功能 访问令牌accessToken 有效期较短通常设置为较短的时间如两小时或根据业务需求自定义如10分钟。 储存用户信息权限等包含用户相关信息如UserID、Username等。 用于前端与后端之间的通信认证前端在每次请求时携带此令牌进行校验。 刷新令牌refreshToken 有效期较长可以设置为一星期、一个月或更长时间具体根据业务需求自定义。 不储存额外信息只储存用户id用于在accessToken过期后重新生成新的accessToken。 由于有效期长因此降低了用户需要频繁登录的频率。 2.双Token方案的优点 增强安全性通过短期有效的accessToken和长期有效的refreshToken的结合即使accessToken泄露攻击者也只能在有限时间内进行模拟用户行为降低了安全风险。 提升用户体验由于refreshToken的存在用户无需频繁登录特别是在长时间操作或后台服务场景下提高了用户体验。 3.实现流程 登录用户输入用户名和密码进行登录后端验证成功后生成accessToken和refreshToken并发送给前端。 请求校验前端在每次请求时携带accessToken进行校验如果accessToken有效则允许请求继续如果无效但refreshToken有效则使用refreshToken重新生成accessToken。 令牌刷新当accessToken过期但refreshToken未过期时前端可以使用refreshToken向后端请求新的accessToken无需用户重新登录。 登出用户登出时后端需要同时使accessToken和refreshToken失效以确保用户登出后的安全性。 二、具体实现 1.后端实现 1.1 jwt工具类 package com.etime.util;import io.jsonwebtoken.*;import java.util.Date; import java.util.Map; import java.util.UUID;/*** Date 2024/6/10 10:04* Author liukang**/ public class JwtUtil { // private static long expire 1000*60*5;// 单位是毫秒private static String secret secret;/*** 创建jwt* author liukang* date 10:36 2024/6/10* param expire* param map* return java.lang.String**/public static String generateToken(long expire, Map map){// 床jwt构造器JwtBuilder jwtBuilder Jwts.builder();// 生成jwt字符串String jwt jwtBuilder//头部.setHeaderParam(typ,JWT).setHeaderParam(alg,HS256)// 载荷.setClaims(map) // 设置多个自定义数据 位置只能放在前面如果放在后面那前面的载荷会失效.setId(UUID.randomUUID().toString())// 唯一标识.setIssuer(liukang)// 签发人.setIssuedAt(new Date())// 签发时间.setSubject(jwtDemo)// 主题.setExpiration(new Date(System.currentTimeMillis()expire))//过期时间// 自定义数据 // .claim(uname,liukang)// 签名.signWith(SignatureAlgorithm.HS256,secret).compact();return jwt;}/*** 创建jwt* author liukang* date 10:36 2024/6/10* param expire* return java.lang.String**/public static String generateToken(long expire){// 床jwt构造器JwtBuilder jwtBuilder Jwts.builder();// 生成jwt字符串String jwt jwtBuilder//头部.setHeaderParam(typ,JWT).setHeaderParam(alg,HS256)// 载荷.setId(UUID.randomUUID().toString())// 唯一标识.setIssuer(liukang)// 签发人.setIssuedAt(new Date())// 签发时间.setSubject(jwtDemo)// 主题.setExpiration(new Date(System.currentTimeMillis()expire))//过期时间// 自定义数据 // .claim(uname,liukang)// 签名.signWith(SignatureAlgorithm.HS256,secret).compact();return jwt;}/*** 解析jwt* author liukang* date 10:36 2024/6/10* param jwt* return io.jsonwebtoken.Claims**/public static Claims parseToken(String jwt){JwsClaims claimsJws Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt);Claims playload claimsJws.getBody();return playload;} } 1.2 响应工具类 代码如下示例 package com.etime.util;import com.etime.vo.ResponseModel; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.MediaType;import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;/*** Date 2024/6/10 10:00* Author liukang**/ public class ResponseUtil {public static void write(ResponseModel rm, HttpServletResponse response) throws IOException {// 构造响应头response.setContentType(MediaType.APPLICATION_JSON_VALUE);response.setCharacterEncoding(utf-8);// 解决跨域问题 设置跨域头response.setHeader(Access-Control-Allow-Origin,*);// 输出流PrintWriter out response.getWriter();// 输出out.write(new ObjectMapper().writeValueAsString(rm));// 关闭流out.close();} } 1.3 实体类 登录用户实体类 package com.etime.entity;import lombok.Data;/*** Date 2024/6/10 10:39* Author liukang**/ Data public class User {private String username;private String password; } 响应vo类 package com.etime.vo;import lombok.Data;import java.util.Objects;/*** Date 2024/6/10 10:37* Author liukang**/ Data public class ResponseModel {private Integer code;private String msg;private Object token;public ResponseModel(Integer code, String msg, Object token) {this.code code;this.msg msg;this.token token;} } 1.4 过滤器 package com.etime.filter;import com.etime.util.JwtUtil; import com.etime.util.ResponseUtil; import com.etime.vo.ResponseModel; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpMethod; import org.springframework.http.HttpRequest; import org.springframework.util.StringUtils;import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** Description jwt过滤器* Date 2024/6/10 9:46* Author liukang**/ WebFilter(urlPatterns /*) // 过滤所有路径 public class JwtFilter implements Filter {Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 得到两个对象HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse response (HttpServletResponse) servletResponse;//直接放行if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){filterChain.doFilter(request,response);return;}String requestURI request.getRequestURI(); // 不含主机和端口号if(requestURI.contains(/login)){filterChain.doFilter(request,response);return;}// 得到请求头的信息accessTokenString token request.getHeader(accessToken);if(!StringUtils.hasText(token)){//响应前端错误的消息提示ResponseModel responseModel new ResponseModel(500,failure,令牌缺失);ResponseUtil.write(responseModel,response);return;}// 解析Token信息try {JwtUtil.parseToken(token);}catch (Exception e){//响应前端错误的消息提示ResponseModel responseModel new ResponseModel(401,failure,令牌过期);ResponseUtil.write(responseModel,response);return;}filterChain.doFilter(request,response);} } 1.5 controller 登录Controller package com.etime.controller;import com.etime.entity.User; import com.etime.util.JwtUtil; import com.etime.vo.ResponseModel; import org.springframework.web.bind.annotation.*;import java.util.HashMap; import java.util.Map;/*** Date 2024/6/10 10:38* Author liukang**/ RestController CrossOrigin public class LoginController {PostMapping(/login)public ResponseModel login(RequestBody User user){Integer code 200;String msg success;String accessToken null;String refreshToken null;Map tokenMap new HashMap();if(user.getUsername().equals(admin)user.getPassword().equals(123)){// 生成jwtaccessToken JwtUtil.generateToken(1000*10);// 设置有效期为10srefreshToken JwtUtil.generateToken(1000*30);// 设置有效期为30stokenMap.put(accessToken,accessToken);tokenMap.put(refreshToken,refreshToken);}else {code 500;msg failure;}return new ResponseModel(code,msg,tokenMap);}} 测试请求Controller package com.etime.controller;import com.etime.vo.ResponseModel; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController;/*** Date 2024/6/10 12:51* Author liukang**/ CrossOrigin RestController public class TestController {PostMapping(/test)public ResponseModel test() {return new ResponseModel(200,success,测试请求接口成功!);}} 刷新Token的Controller package com.etime.controller;import com.etime.util.JwtUtil; import com.etime.vo.ResponseModel; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.HashMap; import java.util.Map;/*** Date 2024/6/10 15:48* Author liukang**/ CrossOrigin RestController public class NewTokenController {GetMapping(/newToken)public ResponseModel newToken(){String accessToken JwtUtil.generateToken(1000*10);String refreshToken JwtUtil.generateToken(1000*30);Map tokenMap new HashMap();tokenMap.put(accessToken,accessToken);tokenMap.put(refreshToken,refreshToken);return new ResponseModel(200,success,tokenMap);} } 1.6 启动类 package com.etime;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan;/*** Author liukang* Date 2022/7/4 11:32*/ SpringBootApplication ServletComponentScan(basePackages com.etime.filter)// 这个包下激活WebFilter这个注解 public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);} } 2、前端实现 2.1 登录页面 templatediv classhelloform用户名input v-modelusername/br密码input v-modelpassword /brbutton clicklogin登录/button/form/div/templatescriptexport default {data () {return {username:,password:,}},methods:{login(){this.axios.post(http://localhost:8088/login,{username:this.username,password:this.password,}).then(response {console.log(response.data);if(response.data.code200){sessionStorage.setItem(accessToken,response.data.token.accessToken)sessionStorage.setItem(refreshToken,response.data.token.refreshToken)this.$router.push({ path: index});}}).catch(error {console.error(error);});}},}/scriptstyle scoped/style 2.2 index页面 templatedivbutton clicktest请求受保护的接口/button/div/templatescript import intercepterConfig from ./js/configexport default {data () {return {}},methods:{test(){const accessToken sessionStorage.getItem(accessToken)let token nullif(accessToken){token accessToken}// console.log(token)this.axios.post(http://localhost:8088/test,{},/*{headers:{accessToken:token}}*/).then(response {// if(response.data.code200){console.log(response.data);// }}).catch(error {console.error(error);});},},}/scriptstyle scoped/style 2.3 请求拦截器和响应拦截器 import axios from axios; //axios请求拦截器 axios.interceptors.request.use(config{// 正确的请求拦截器let token null;let url config.url// url.indexOf(/newToken)-1 如果是刷新Token的请求 不用在拦截器里面加accessToken 这个请求已经在请求头中设置accessToken加了会覆盖if(sessionStorage.getItem(accessToken)!null url.indexOf(/newToken)-1){token sessionStorage.getItem(accessToken)config.headers[accessToken] token}// 加入头信息的配置return config // 这句没写请求会发不出去},error{ // 出现异常的请求拦截器return Promise.reject(error)}) // axios响应拦截器 axios.interceptors.response.use(async res {// 判断 401状态码 自动续期if (res.data.code 401 !res.config.isRefresh) {//!res.config.isRefresh 不是刷新Token的请求才拦截 是则不拦截// 1.自动续期const res2 await getNewToken()if(res2.data.code 200){console.log(自动续期成功new Date().toLocaleString())// 2.更新sessionStorage里面的Token 没有这一步会死循环sessionStorage.setItem(accessToken,res2.data.token.accessToken)sessionStorage.setItem(refreshToken,res2.data.token.refreshToken)//3.重新发送请求res await axios.request(res.config)// res.config 代表请求的所有参数这里是上一次请求的所有参数包括url和携带的所有数据}}return res // 将重新请求的响应作为响应返回},error{return Promise.reject(error)})function getNewToken(){let url http://localhost:8088/newTokenlet token nullif(sessionStorage.getItem(refreshToken)!null){token sessionStorage.getItem(refreshToken)}return axios.get(url,{headers:{accessToken:token},isRefresh:true})// 注意这里参数是accessToken:token 因为后端过滤器里面获取的是accessToken所以要写这个不然过滤器通不过过滤器 } 效果展示 1.登录页面 2.输入用户名和密码点击【登录】 3.点击【请求受保护的资源】按钮 3.等待10秒accessToken过期但refreshToken未过期时点击【请求受保护的资源】按钮 4.等待30秒后refreshToken和accessToken都过期再次点击【请求受保护的资源】按钮
http://www.hkea.cn/news/14563845/

相关文章:

  • 中国设计网站官网地址wordpress 迁移插件
  • 二手交易网站建设内容策划推广平台大全
  • 网络传媒网站网站策划方案 优帮云
  • 如何建设淘宝客网站手机网站制作
  • 整站优化该怎么做证件查询官网入口
  • 哪里有网站app制作wordpress post date
  • 富阳网站设计网站建设佰金手指科杰六
  • 东台网站制作公司上海免费建站模板
  • 网站建设后台管理便捷做网站文字怎么围绕图片
  • 做网站的公司现在还 赚钱吗6wordpress 扁平化主题
  • 重庆网站设计智能 乐云践新怎么看一个网站的cms
  • 哪个网站的ppt模板最好福鼎网站建设培训
  • 2017最新网站icp备案哪里建网站性价比高
  • 东莞市住房建设局网站首页汉中市网站建设
  • 创同盟网站一般的学校网站怎么做
  • 厦门网盛网站开发内部网站可以做ipc备案
  • 网站前端代码有哪些问题网站建设及管理制度文章
  • 国企门户网站建设方案90设计是免费下载吗
  • 漂亮的网站框架网站内容好
  • 再网站里做商家店铺深圳互联网公司招聘信息
  • 建站教程下载注册城乡规划师通过率
  • 怎么查出这个网站是谁做的国外网站做调查
  • 建站快车源码河北省建设厅网站怎么登陆
  • 服装电子商务网站建设与实现绍兴seo淄博公司
  • 深圳推广公司网站建设书模板购物网站建设合同
  • 个人网站域名备案流程品牌网站建设預定大蝌蚪
  • 网站制作创业微信平台专业网站建设
  • 网站备案弊端滨州市滨城区建设局网站
  • 理查德西尔斯做的网站wordpress 收费插件
  • 承德房地产网站建设seo工具软件