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

网站开发人员资质沧州网站建设专业定制

网站开发人员资质,沧州网站建设专业定制,成都网站建设成都网站制作,上海百度关键词搜索推广服务在 Web 应用中#xff0c;登录验证是保障系统安全的核心环节。本文将结合具体接口文档#xff0c;详细讲解如何基于 JWT#xff08;JSON Web Token#xff09;实现登录验证功能#xff0c;包括 JWT 配置、工具类封装、登录流程处理等关键步骤#xff0c;帮助开发者快速理…在 Web 应用中登录验证是保障系统安全的核心环节。本文将结合具体接口文档详细讲解如何基于 JWTJSON Web Token实现登录验证功能包括 JWT 配置、工具类封装、登录流程处理等关键步骤帮助开发者快速理解并落地类似功能。一、需求分析接口文档解读本次实现的登录验证功能需满足以下接口文档要求核心接口包括接口名称请求方式接口地址核心功能描述生成验证码GET/captcha生成验证码并存储用于登录校验用户登录POST/login校验用户信息生成 JWT 令牌返回Token 校验GET/checkToken验证令牌有效性退出登录POST/logout清除令牌退出登录其中登录接口/login 是核心需接收前端传递的username用户名、password密码、captcha验证码、uuid验证码唯一标识验证通过后返回token令牌和expire令牌过期时间。二、技术选型JWT 为何适合登录验证JWT 是一种基于 JSON 的轻量级令牌用于在客户端和服务器之间安全传递信息。其优势在于无状态服务器无需存储会话信息令牌本身包含用户身份等关键信息适合分布式系统。安全性通过签名机制确保令牌不被篡改。自包含可在令牌中嵌入用户权限等信息减少数据库查询。本次使用jjwt库实现 JWT 功能配合 Redis 存储验证码和令牌兼顾安全性与效率。三、实现步骤从配置到接口落地1. JWT 配置基础参数定义首先在配置文件中定义 JWT 的核心参数用于生成和验证令牌 jwt:secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gH # 签名密钥需保密expire: 86400000 # 令牌过期时间毫秒此处为24小时subject: door # 令牌主题可选用于标识令牌用途 secret签名密钥生成令牌时用于加密验证时用于解密需确保安全性建议生产环境使用更长更复杂的密钥。expire对应登录接口返回的expire字段控制令牌有效期。2. 依赖导入引入 JWT 工具库在pom.xml中引入jjwt依赖用于处理 JWT 的生成与解析 dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.1/version /dependency 该版本稳定且功能完善支持 HS256 等签名算法满足本次需求。3. JWT 工具类封装令牌核心操作封装JwtUtil工具类实现令牌的生成、校验等核心功能代码如下 package com.qcby.community.util;import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils;import java.util.Date; import java.util.UUID;ConfigurationProperties(prefix jwt) // 绑定配置文件中jwt前缀的参数 Component public class JwtUtil {private long expire; // 过期时间从配置文件注入private String secret; // 签名密钥从配置文件注入private String subject; // 令牌主题从配置文件注入/*** 生成令牌* param userId 用户ID作为令牌中的核心标识* return 生成的JWT令牌字符串*/public String createToken(String userId) {return Jwts.builder().claim(userId, userId) // 自定义载荷存储用户ID.setSubject(subject) // 令牌主题.setExpiration(new Date(System.currentTimeMillis() expire)) // 过期时间.setId(UUID.randomUUID().toString()) // 唯一标识可选.signWith(SignatureAlgorithm.HS256, secret) // 使用HS256算法签名.compact(); // 组装令牌}/*** 校验令牌有效性* param token 待校验的令牌* return 校验结果true有效false无效*/public boolean checkToken(String token){if(StringUtils.isEmpty(token)){return false; // 令牌为空直接无效}try {// 解析令牌自动验证签名和过期时间JwsClaims claimsJws Jwts.parser().setSigningKey(secret).parseClaimsJws(token);return true; // 解析成功令牌有效} catch (Exception e) {// 解析失败签名错误、过期等令牌无效return false;}}// getter/setter用于注入配置参数public long getExpire() { return expire; }public void setExpire(long expire) { this.expire expire; }public String getSecret() { return secret; }public void setSecret(String secret) { this.secret secret; }public String getSubject() { return subject; }public void setSubject(String subject) { this.subject subject; } } 核心说明createToken方法根据用户 ID 生成令牌包含用户标识、过期时间等信息通过secret签名确保不可篡改对应登录接口成功后返回的token。checkToken方法用于验证令牌有效性包括签名正确性和是否过期对应/checkToken接口的核心逻辑。4. 登录接口实现完整流程处理登录接口/login是验证流程的核心需完成验证码校验、用户信息验证、令牌生成等步骤代码如下 RestController public class LoginController {Autowiredprivate JwtUtil jwtUtil; // 注入JWT工具类Autowiredprivate UserService userService; // 用户服务Autowiredprivate RedisTemplate redisTemplate; // Redis模板用于存储验证码和令牌/*** 处理登录请求* param loginForm 前端传递的登录参数包含username、password、captcha、uuid* return 登录结果成功返回token和expire失败返回错误信息*/PostMapping(/login)public Result login(RequestBody LoginForm loginForm){// 1. 验证码校验基于Redis// 从Redis获取验证码键为uuid对应生成验证码接口返回的uuidString code (String) redisTemplate.opsForValue().get(loginForm.getUuid());if(code null){return Result.ok().put(status, fail).put(data, 验证码已过期);}if(!code.equals(loginForm.getCaptcha())){return Result.ok().put(status, fail).put(data, 验证码错误);}// 2. 验证用户名QueryWrapperUser queryWrapper new QueryWrapper();queryWrapper.eq(username, loginForm.getUsername());User user userService.getOne(queryWrapper);if(user null){return Result.error(用户名错误);}// 3. 验证密码SHA256加密比对String password SecureUtil.sha256(loginForm.getPassword()); // 前端密码加密if(!password.equals(user.getPassword())){ // 与数据库中加密后的密码比对return Result.error(密码错误);}// 4. 验证用户状态是否被锁定if(user.getStatus() 0) {return Result.error(账号已被锁定请联系管理员);}// 5. 登录成功生成令牌并返回String token jwtUtil.createToken(String.valueOf(user.getUserId())); // 生成token// 将token存入Redis键为communityuser-用户ID过期时间与token一致redisTemplate.opsForValue().set(communityuser-user.getUserId(), token, jwtUtil.getExpire(), TimeUnit.MILLISECONDS);// 组装返回结果符合接口文档data包含token和expireMapString,Object map new HashMap();map.put(token, token);map.put(expire, jwtUtil.getExpire());return Result.ok().put(data, map);} } 流程对应接口文档说明参数接收LoginForm包含uuid验证码标识、captcha验证码、username用户名、password密码完全匹配登录接口的请求参数。验证码校验通过uuid从 Redis 获取验证码生成验证码接口会将uuid和code存入 Redis验证过期和正确性对应生成验证码接口的交互逻辑。返回结果登录成功时返回data对象包含token和expire与接口文档中登录成功的返回结构一致失败时返回对应错误信息。5. Token 校验接口实现基于JwtUtil的checkToken方法实现/checkToken接口 GetMapping(/checkToken) public Result checkToken(HttpServletRequest request){// 从请求头获取token假设前端将token放在Authorization头中String token request.getHeader(Authorization);boolean valid jwtUtil.checkToken(token);if(valid){return Result.ok().put(status, ok);}else{return Result.ok().put(status, error);} } 该接口直接调用JwtUtil的校验方法返回status为ok或error完全符合接口文档要求。可以先在前端的 permission.js里代码进行修改 import router from ./router; import store from ./store; import { Message } from element-ui; import NProgress from nprogress; import nprogress/nprogress.css; import { getToken } from /utils/auth; import getPageTitle from /utils/get-page-title; import { checkToken } from /api/sys/login;NProgress.configure({ showSpinner: false });const whiteList [/login, /auth-redirect]; // 没有重定向白名单router.beforeEach(async (to, from, next) {NProgress.start();// 设置页面标题document.title getPageTitle(to.meta.title);let token getToken();if (token) {//校验TokencheckToken(token).then(res {if (res.code 200 res.status error) {next({ path: /error });}});if (to.path /login) {// 如果已登录请重定向到主页next({ path: / });NProgress.done();} else {// 确定用户是否通过getInfo获取了权限角色const hasRoles store.getters.roles store.getters.roles.length 0;if (hasRoles) {next();} else {next();// try {// // 获取用户信息// const { routers } await store.dispatch(user/getInfo);// // 基于角色生成可访问的路由映射// const accessRoutes await store.dispatch(// permission/generateRoutes,// { routers }// );// // 动态添加可访问的路由// router.addRoutes(accessRoutes);// // hack方法 确保addRoutes已完成// // 设置replace:true这样导航就不会留下历史记录// next({ ...to, replace: true });// } catch (error) {// // 删除令牌并转到登录页重新登录// await store.dispatch(user/resetToken);// Message.error(error || Has Error);// // next(/login?redirect${to.path})// next(/login);// NProgress.done();// }}}} else {/* 没有token */if (whiteList.indexOf(to.path) ! -1) {// 在免登录白名单直接进入next();} else {// 否则全部重定向到登录页// next(/login?redirect${to.path})next(/login);NProgress.done();}} });router.afterEach(() {// 结束进度条NProgress.done(); }); 修改前的逻辑注释部分原本的代码实现了完整的权限控制流程用户登录后获取用户角色和权限信息通过 store.dispatch(user/getInfo)。根据用户角色动态生成可访问的路由通过 store.dispatch(permission/generateRoutes)。使用 router.addRoutes() 动态添加路由确保用户只能访问其权限范围内的页面。修改后的逻辑直接 next()当你将这部分代码注释掉并直接调用 next() 时会发生以下变化权限控制失效所有用户无论是否登录、拥有何种角色都可以访问任意路由包括需要特定权限的页面。例如普通用户可能可以访问管理员页面。动态路由未生成router.addRoutes() 未执行意味着基于用户角色的动态路由配置不会生效。应用可能只能访问静态定义的基础路由。用户信息未获取store.dispatch(user/getInfo) 未执行Vuex 中不会存储用户角色、权限等信息导致页面上可能无法正确显示与用户相关的内容如用户名、头像、导航菜单。
http://www.zqtcl.cn/news/554022/

相关文章:

  • 建设手机网站的目的广告制作行业发展前景
  • 手工艺品网站建设目的长春有哪些网络设计公司
  • 重庆建设工程招标网站淮南58同城网
  • 有域名在本机上做网站psd素材
  • 做拍拍拍拍网站网站宣传的劣势
  • 建设银行官方网站诚聘英才亚马逊店铺出售网站
  • 佛山房地产网站建设万网域名查询接口
  • 新建的网站必须要备案吗优购物网
  • 陕西省住房和城乡建设厅官方网站智能网站建设制作
  • 英语故事网站建设镇江大港信息港
  • 接单做一个网站多少钱商河网站建设
  • 网站建设s南昌网站建设服务
  • 免费的素材网站有哪些重庆网页设计公司排名
  • 内网网站建设汇报即商通网站建设推广
  • 企业建站系统是什么学校的网站怎么做的
  • 哪个大学的网站做的最好看网页制作教材素材
  • 南里商濮阳网站建设福田附件网站建设公司
  • 监控性能网站模板网页设计公司找哪家
  • 校园网站建设教程安卓小程序开发入门
  • 找人做网站需要注意什么seo工作
  • 做外贸有哪些好的网站有哪些内容响应式网站wordpress摄影
  • iis 7.0 搭建网站做门户网站公司
  • 织梦网站模版官网霸屏seo服务
  • 人工智能的网站开发app流程
  • 国外做贸易网站淄川区建设局网站
  • 做网站第一步要干啥wordpress 金币插件
  • 合肥如何做百度的网站网络服务主要包括哪几项
  • 影视网站的设计与实现网站搭建培训
  • 网站优化 前端怎么做泉州建设培训中心网站
  • 专业的无锡网站建设电子邮件无法发送wordpress