记录一下验证token的代码

代码是抄来的,做个记录以后用
<!-- JWT依赖 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>

 

 

package com.beef.shop.common.config;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 * JWT的token,区分大小写
 */
@ConfigurationProperties(prefix = "config.jwt")
@Component
public class JwtConfig {

    private String secret;
    private long expire;
    private String header;

    /**
     * 生成token
     * @param subject
     * @return
     */
    public String createToken (String subject){
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);//过期时间

        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(subject)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
    /**
     * 获取token中注册信息
     * @param token
     * @return
     */
    public Claims getTokenClaim (String token) {
        try {
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        }catch (Exception e){
//            e.printStackTrace();
            return null;
        }
    }
    /**
     * 验证token是否过期失效
     * @param expirationTime
     * @return
     */
    public boolean isTokenExpired (Date expirationTime) {
        return expirationTime.before(new Date());
    }

    /**
     * 获取token失效时间
     * @param token
     * @return
     */
    public Date getExpirationDateFromToken(String token) {
        return getTokenClaim(token).getExpiration();
    }
    /**
     * 获取用户名从token中
     */
    public String getUsernameFromToken(String token) {
        return getTokenClaim(token).getSubject();
    }

    /**
     * 获取jwt发布时间
     */
    public Date getIssuedAtDateFromToken(String token) {
        return getTokenClaim(token).getIssuedAt();
    }

    // --------------------- getter & setter ---------------------

    public String getSecret() {
        return secret;
    }
    public void setSecret(String secret) {
        this.secret = secret;
    }
    public long getExpire() {
        return expire;
    }
    public void setExpire(long expire) {
        this.expire = expire;
    }
    public String getHeader() {
        return header;
    }
    public void setHeader(String header) {
        this.header = header;
    }
}

定义异常

package com.beef.shop.common.config;


import com.beef.shop.common.utils.ReturnInfo;
import com.beef.shop.common.utils.StatusInfo;
import io.jsonwebtoken.SignatureException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class PermissionHandler {

    @ExceptionHandler(value = { SignatureException.class })
    @ResponseBody
    public String authorizationException(SignatureException e){
        return ReturnInfo.returnJsonInfo(StatusInfo.FAIL,"失败");
    }
}

配置token过滤器

package com.beef.shop.common.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private JwtConfig jwtConfig ;
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws SignatureException {
        /** 地址过滤 */
        String uri = request.getRequestURI() ;
        if (uri.contains("/login")){
            return true ;
        }
        /** Token 验证 */
        String token = request.getHeader(jwtConfig.getHeader());
        if(StringUtils.isEmpty(token)){
            token = request.getParameter(jwtConfig.getHeader());
        }
        if(StringUtils.isEmpty(token)){
            throw new SignatureException(jwtConfig.getHeader()+ "不能为空");
        }

        Claims claims = null;
        try{
            claims = jwtConfig.getTokenClaim(token);
            if(claims == null || jwtConfig.isTokenExpired(claims.getExpiration())){
                throw new SignatureException(jwtConfig.getHeader() + "失效,请重新登录。");
            }
        }catch (Exception e){
            throw new SignatureException(jwtConfig.getHeader() + "失效,请重新登录。");
        }

        /** 设置 identityId 用户身份ID */
        request.setAttribute("identityId", claims.getSubject());
        return true;
    }
}
注册拦截器
package com.beef.shop.common.config;


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Resource
    private TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
    }
}

登录验证

package com.beef.shop.controller;


import com.alibaba.fastjson.JSONObject;

import com.beef.shop.common.config.JwtConfig;
import com.beef.shop.common.utils.ReturnInfo;
import com.beef.shop.common.utils.StatusInfo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
public class TokenController {

    @Resource
    private JwtConfig jwtConfig ;

    /**
     * 用户登录接口
     * @param userName
     * @param passWord
     * @return
     */
    @PostMapping("/login")
    public String login (@RequestParam("userName") String userName,
                              @RequestParam("passWord") String passWord){
        JSONObject json = new JSONObject();

        /** 验证userName,passWord和数据库中是否一致,如不一致,直接return ResultTool.errer(); 【这里省略该步骤】*/

        // 这里模拟通过用户名和密码,从数据库查询userId
        // 这里把userId转为String类型,实际开发中如果subject需要存userId,则可以JwtConfig的createToken方法的参数设置为Long类型
        String userId = 5 + "10011";
        String token = jwtConfig.createToken(userId) ;
        if (!StringUtils.isEmpty(token)) {
            json.put("token",token) ;
        }
        return ReturnInfo.returnJsonInfo(StatusInfo.SUCCESS, json);
    }

    /**
     * 需要 Token 验证的接口
     */
    @PostMapping("/info")
    public String info (){
        return ReturnInfo.returnJsonInfo(StatusInfo.SUCCESS, "info");
    }

    /**
     * 根据请求头的token获取userId
     * @param request
     * @return
     */
    @GetMapping("/getUserInfo")
    public String getUserInfo(HttpServletRequest request){
        String usernameFromToken = jwtConfig.getUsernameFromToken(request.getHeader("token"));
        return ReturnInfo.returnJsonInfo(StatusInfo.SUCCESS, usernameFromToken);
    }

    /*
        为什么项目重启后,带着之前的token还可以访问到需要info等需要token验证的接口?
        答案:只要不过期,会一直存在,类似于redis
     */

}

 

spring.application.name=springboot-jwt
# 加密密钥
config.jwt.secret= abcdefg1234567
# token有效时长
config.jwt.expire=3600
# header 名称
config.jwt.header=token

在postman调试post请求

http://localhost:9091/login?userName=zhangsan&passWord=123

{"result":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1MTAwMTEiLCJpYXQiOjE2MDAzMjc5ODQsImV4cCI6MTYwMDMzMTU4NH0.r0vmHp1_N7sMI51UMvuApiB1O0Vzo9HOIzWyuUlOZUH6Sw9fzOG4sOQlv64GMlR_6dt8d526czclhel08fiUKQ"},"statusMsg":"成功","success":true,"unAuthorizedRequest":false,"statusCode":"200"}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你可以使用以下代码来写出短信验证:from django.conf import settings from django.contrib.auth.tokens import default_token_generatordef send_sms_verification(user): token = default_token_generator.make_token(user) phone_number = user.phone_number message = '您的验证码是{}。'.format(token) send_sms(phone_number, message) ### 回答2: 使用Python中的Django框架编写短信验证代码可以通过以下步骤实现: 1. 创建Django项目并配置好相关设置。 2. 在项目中创建一个独立的应用,用于处理短信验证功能。 3. 在应用的models.py文件中定义一个名为VerificationCode的模型类,用于存储验证码相关信息。该模型可以包含字段如下: ``` from django.db import models class VerificationCode(models.Model): phone = models.CharField(max_length=20) code = models.CharField(max_length=6) created_time = models.DateTimeField(auto_now_add=True) ``` 4. 在应用的views.py文件中,编写一个视图函数用于处理验证码的发送和验证。该函数可以包含以下步骤: - 生成6位随机验证码; - 调用第三方短信服务商的接口发送短信至指定手机号; - 将验证码和手机号保存到VerificationCode模型中; - 返回发送成功或失败的响应。 例如: ``` from django.http import JsonResponse import random from .models import VerificationCode def send_verification_code(request): phone = request.GET.get('phone') code = str(random.randint(100000, 999999)) # 调用短信服务商接口发送短信 verification_code = VerificationCode(phone=phone, code=code) verification_code.save() return JsonResponse({'status': 'success'}) ``` 5. 在应用的views.py文件中,编写另一个视图函数用于验证用户输入的验证码。该函数可以包含以下步骤: - 获取用户输入的手机号和验证码; - 查询VerificationCode模型中是否存在对应手机号和验证码的记录; - 根据查询结果返回验证成功或失败的响应。 例如: ``` from django.http import JsonResponse from .models import VerificationCode def verify_code(request): phone = request.GET.get('phone') code = request.GET.get('code') if VerificationCode.objects.filter(phone=phone, code=code).exists(): return JsonResponse({'status': 'verified'}) else: return JsonResponse({'status': 'failed'}) ``` 6. 在项目的urls.py文件中配置相关路由,将以上两个视图函数映射到相应URL。 7. 运行Django项目,通过访问对应的URL即可实现短信验证码的发送和验证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值