手机号快捷登录功能的实现

目录

一、shiro框架的配置

二、图形验证码接口(游客接口)

2.1 pojo

2.2  controller

2.3 service和serviceImpl

 2.4 图形验证码工具类

三、短信发送接口(游客接口)

3.1 阿里短信发送工具类

3.2 controller

 3.3 service和serviceImpl

四、登录接口(游客接口)

4.1 controller

4.2 Shiro-SmsToken

4.3 realm

五、登录后的权限验证

5.1 Shiro-UUIDToken

5..2 realm


一、shiro框架的配置

拦截器配置

package com.itqq.interceptor;

import com.itqq.shiro.UUIDToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:使用过滤器用户在进行权限验证时必须要先认证,一个个加太麻烦
 * 所以在拦截器中统一进行认证
 *
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            String token = request.getHeader("token");
//            使用Shiro框架的SecurityUtils.getSubject()方法获取当前的Subject(即用户身份)
            Subject subject = SecurityUtils.getSubject();
//            将token传给UUIDRealm进行认证
            subject.login(new UUIDToken(token));
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }
}
package com.itqq.config;

import com.itqq.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:
 */
@Configuration
public class MyConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//        将loginInterceptor这个拦截器注册到Spring Boot中,并排除对/employee/login(登录)这个路径的拦截
        registry.addInterceptor(loginInterceptor)
                .excludePathPatterns("/employee/login")
                .excludePathPatterns("/employee/captcha")
                .excludePathPatterns("/employee/sendSms");
    }
}

使用shiro框架必须的配置

package com.itqq.config;

import com.itqq.realm.MyRealm;
import com.itqq.realm.SmsRealm;
import com.itqq.realm.UUIDRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:shiro整合Spring的配置文件
 */
@Configuration
public class ShiroConfig {
    @Autowired
    private MyRealm myRealm;
    @Autowired
    private UUIDRealm uuidRealm;
    @Autowired
    private SmsRealm smsRealm;
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
    @Bean(name = "lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager());
        return new AuthorizationAttributeSourceAdvisor();
    }
    // 设置安全管理器securityManager
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        List<Realm> realms = new ArrayList<>();
        realms.add(myRealm);
        realms.add(uuidRealm);
        realms.add(smsRealm);
        securityManager.setRealms(realms);
        return securityManager;
    }
    // 设置filter
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager( securityManager());
        shiroFilter.setLoginUrl("/anon");
        shiroFilter.setUnauthorizedUrl("/anon");
        return shiroFilter;
    }
//    @Bean
//    public MyRealm myRealm(){
//        return new MyRealm();
//    }
}

二、图形验证码接口(游客接口)

2.1 pojo

package com.itqq.pojo;

import lombok.Data;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:验证码封装对象
 */
@Data
public class Captcha implements Serializable {
    private static final long serialVersionUID = 1495038284838382L;
    //    图型验证码供前端使用
    private String base64Str;
    //    唯一标识符--获取验证码
    private String client;
//    用户传入的验证码(值)
    private String captcha;

//    用户接收的手机号码
    private String phone;

}

2.2  controller

//       1. 图形验证码接口
//       请求地址:http://*****/user/captcha
//       请求方式:GET
//       请求参数:无
//       返回值: 图片--图片验证码,client

//    获取图形验证码接口
    @GetMapping("captcha")
    public Result captcha() {
        Captcha validateCode = employeeService.getValidateCode();
        log.info(validateCode.toString());
        return Result.success(employeeService.getValidateCode());

    }

2.3 service和serviceImpl

Captcha getValidateCode();
public Captcha getValidateCode() {
        ValidateCodeUtil.Validate validate = ValidateCodeUtil.getRandomCode();
        Captcha captcha = new Captcha();
//        将生成的base64格式的图形验证码放到captcha对象上
        captcha.setBase64Str(validate.getBase64Str());
//        唯一标识符,这里使用uuid
        captcha.setClient("AHCTPAC"+ UUID.randomUUID().toString().replace("-","").toUpperCase());
//        将标识符作为key,验证码值validate.getValue作为value(因为验证码是随机生成的,并发量大的话会重复),存入redis中
//        redis String类型
        redisTemplate.opsForValue().set(captcha.getClient(), validate.getValue());
        redisTemplate.expire(captcha.getClient(),5, TimeUnit.MINUTES);//10分钟过期时间
        log.info("验证码:{}",validate.getValue());
//        返回图形验证码用于前端展示
        return captcha;
    }

 2.4 图形验证码工具类

package com.itqq.utils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Base64;
import java.util.Random;

import javax.imageio.ImageIO;

public class ValidateCodeUtil {

    private static Validate validate = null; //验证码类,用于最后返回此对象,包含验证码图片base64和真值
    private static Random random = new Random(); //随机类,用于生成随机参数
    private static String randString = "0123456789";//随机生成字符串的取值范围
    private static int width = 100;     //图片宽度
    private static int height = 40;    //图片高度
    private static int StringNum = 6;  //字符的数量
    private static int lineSize = 40;  //干扰线数量

    //将构造函数私有化 禁止new创建
    private ValidateCodeUtil() {
        super();
    }

    /**
     * 获取随机字符,并返回字符的String格式
     * @param index (指定位置)
     * @return
     */
    private static String getRandomChar(int index) {
        //获取指定位置index的字符,并转换成字符串表示形式
        return String.valueOf(randString.charAt(index));
    }
    /**
     * 获取随机指定区间的随机数
     * @param min (指定最小数)
     * @param max (指定最大数)
     * @return
     */
    private static int getRandomNum(int min,int max) {
        return (int)(Math.random()* (max-min+1))+min;
    }

    /**
     * 获得字体
     * @return
     */
    private static Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 25);  //名称、样式、磅值
    }

    /**
     * 获得颜色
     */
    private static Color getRandColor(int frontColor, int backColor) {
        if(frontColor > 255)
            frontColor = 255;
        if(backColor > 255)
            backColor = 255;

        int red = frontColor + random.nextInt(backColor - frontColor - 16);
        int green = frontColor + random.nextInt(backColor - frontColor -14);
        int blue = frontColor + random.nextInt(backColor - frontColor -18);
        return new Color(red, green, blue);
    }

    /**
     * 绘制字符串,返回绘制的字符串
     * @param g
     * @param randomString
     * @param i
     * @return
     */
    private static String drawString(Graphics g, String randomString, int i) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setFont(getFont());   //设置字体
        g2d.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));//设置颜色
        String randChar = String.valueOf(getRandomChar(random.nextInt(randString.length())));
        randomString += randChar;   //组装
        int rot = getRandomNum(5,10);
        g2d.translate(random.nextInt(3), random.nextInt(3));
        g2d.rotate(rot * Math.PI / 180);
        g2d.drawString(randChar, 13*i, 20);
        g2d.rotate(-rot * Math.PI / 180);
        return randomString;
    }

    /**
     * 绘制干扰线
     * @param g
     */
    private static void drawLine(Graphics g) {
        //起点(x,y)  偏移量x1、y1
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));
        g.drawLine(x, y, x + xl, y + yl);
    }

    /**
     * @Description: 生成Base64图片验证码
     */
    public static Validate getRandomCode() {
        validate = validate==null?new Validate():validate;

        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();// 获得BufferedImage对象的Graphics对象
        g.fillRect(0, 0, width, height);//填充矩形
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//设置字体
        g.setColor(getRandColor(110, 133));//设置颜色
        //绘制干扰线
        for(int i = 0; i <= lineSize; i++) {
            drawLine(g);
        }
        //绘制字符
        String randomString = "";
        for(int i = 1; i <= StringNum; i++) {
            randomString = drawString(g, randomString, i);
            validate.setValue(randomString);
        }
        g.dispose();//释放绘图资源
        ByteArrayOutputStream bs = null;
        try {
            bs = new ByteArrayOutputStream();
            ImageIO.write(image, "png", bs);//将绘制得图片输出到流
            String imgsrc = Base64.getEncoder().encodeToString(bs.toByteArray());

            validate.setBase64Str(imgsrc);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                bs = null;
            }
        }
        return validate;
    }

    public static class Validate implements Serializable{
        private static final long serialVersionUID = 1L;
        private String Base64Str;       //Base64 值
        private String value;           //验证码值

        public String getBase64Str() {
            return "data:image/jpeg;base64,"+Base64Str;
        }
        public void setBase64Str(String base64Str) {
            Base64Str = base64Str;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }
}

三、短信发送接口(游客接口)

pojo用的也是Captcha,短信发送我用的是阿里云的短信服务

阿里云申请完短信服务后,牢记id和secret,并写入配置文件如:

aliyun:
  ACCESS_KEY_ID: ************
  ACCESS_KEY_SECRET: ***************

3.1 阿里短信发送工具类

SMSUtils

使用时只需要把senderSms方法的setSignName和setTemplateCode改成自己账号下的签名和模板号,就可使用

package com.itqq.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:
 */
@Component
public class SMSUtils {
    @Value("${aliyun.ACCESS_KEY_ID}")
    private String ACCESS_KEY_ID;
    @Value("${aliyun.ACCESS_KEY_SECRET}")
    private String ACCESS_KEY_SECRET;
    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    private com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填,您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    /**
     * 使用STS鉴权方式初始化账号Client,推荐此方式。
     * @param accessKeyId
     * @param accessKeySecret
     * @param securityToken
     * @return Client
     * @throws Exception
     */
    private com.aliyun.dysmsapi20170525.Client createClientWithSTS(String accessKeyId, String accessKeySecret, String securityToken) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填,您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret)
                // 必填,您的 Security Token
                .setSecurityToken(securityToken)
                // 必填,表明使用 STS 方式
                .setType("sts");
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    public void senderSms(String phone,String code) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = createClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                .setSignName("基尼太美")
                .setTemplateCode("SMS_*********")
                .setPhoneNumbers(phone)
                .setTemplateParam("{\"code\":\"" + code + "\"}");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        com.aliyun.dysmsapi20170525.models.SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);
        com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(resp));

    }
}

3.2 controller

    /**
     *发送短信验证码接口
     * @param "phone",client,captcha
     * @return
     */
    @PostMapping("sendSms")
    public Result sendSms(@RequestBody Captcha captcha) throws Exception {
        return employeeService.sendSms(captcha) ? Result.success("发送成功") : Result.failed("发送失败");
    }

 3.3 service和serviceImpl

boolean sendSms(Captcha captcha) throws Exception;
//    发送短信验证码接口
    @Override
    public boolean sendSms(Captcha captcha) throws Exception {
//        1.判断图形验证码是否正确
        String value = (String) redisTemplate.opsForValue().get(captcha.getClient());
        if (!StringUtils.hasText(value)){
            throw new RuntimeException("图形验证码已过期");
        }
        if (!value.equals(captcha.getCaptcha())){
            throw new RuntimeException("图形验证码错误");
        }
//        判断同一手机号短时间内是否重复发送验证码
        if (redisTemplate.hasKey("expire"+captcha.getPhone())){
            throw new RuntimeException("一分钟内不能重复发送验证码");
        }
//        2.发送验证码
        String code = randomUtil.randomCode();
//        有异常需要抛出
        smsUtils.senderSms(captcha.getPhone()+"",code);
//        3.将短信验证码存入redis中 phone为key,验证码为value
        redisTemplate.opsForValue().set("SMS"+captcha.getPhone(),code);
//        4.短信验证码过期时间
        redisTemplate.expire("SMS"+captcha.getPhone(),5, TimeUnit.MINUTES);
//        5.实现同一手机号一分钟内不能重复发送短信验证码
        redisTemplate.opsForValue().set("expire"+captcha.getPhone(),"0");
        redisTemplate.expire("expire"+captcha.getPhone(),1, TimeUnit.MINUTES);
        return true;
    }
@Component
public class RandomUtil {
    public String randomCode(){
        String code = "";
        for (int i=0;i<6;i++){
            code += (int)(Math.random()*10);
        }
        return code;
    }
}

 

四、登录接口(游客接口)

4.1 controller

/**
     * 登录接口
     * @param smsToken
     * @return
     */
    @PostMapping("login")
    public Result login(@RequestBody SmsToken smsToken) {
//        此token是前端传来的登录信息,这里是phone和短信验证码
        SecurityUtils.getSubject().login(smsToken);
//        登录成功后返回token
        String tokenString = UUID.randomUUID().toString().replace("-", "");
        redisTemplate.opsForValue().set(tokenString, 1);
        return Result.success(tokenString);
    }

4.2 Shiro-SmsToken

package com.itqq.shiro;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.shiro.authc.AuthenticationToken;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SmsToken implements AuthenticationToken, Serializable {
    private static final long serialVersionUID = 8885806135738587998L;
    private Long phone;
    private String code;
    @Override
    public Object getPrincipal() {
        return phone;
    }

    @Override
    public Object getCredentials() {
        return code;
    }
}

4.3 realm

登录时需要对用户输入的手机号进行系统验证,如果不存在则不能登录,也可以不存在直接使用该账号注册,本文没有拓展注册功能,直接输出账号不存在。判断手机号是否纯在需要查数据库。

package com.itqq.realm;

import com.itqq.pojo.Employee;
import com.itqq.service.EmployeeService;
import com.itqq.shiro.SmsToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;


/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:
 */
@Component
public class SmsRealm extends AuthorizingRealm {
    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private RedisTemplate redisTemplate;

    public boolean supports(AuthenticationToken token) {
        return token instanceof SmsToken;
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        Long phone = (Long) token.getPrincipal();
        String captcha = (String) token.getCredentials();
        if(phone == null){
            throw new AuthenticationException("手机号不能为空");
        }
        if(captcha == null){
            throw new AuthenticationException("验证码不能为空");
        }
//        判断手机验证码是否过期
        String captcha1 = (String)redisTemplate.opsForValue().get("SMS" + phone);
        if(!StringUtils.hasText(captcha1)){
            throw new AuthenticationException("短信验证码已过期");
        }
        Employee employee = employeeService.findEmployeeByPhone(phone);
        if(employee == null){
            throw new AuthenticationException("手机号不存在");
        }
//        验证短信验证码是否正确,shiro自带的框架验证
        return new SimpleAuthenticationInfo(employee.getId(),captcha1,getName());
    }
}

五、登录后的权限验证

5.1 Shiro-UUIDToken

package com.itqq.shiro;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.shiro.authc.AuthenticationToken;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: syq
 * @Description:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UUIDToken implements AuthenticationToken, Serializable {
    private static final long serialVersionUID = 8884806189738587998L;
    private String uuid;
    @Override
    public Object getPrincipal() {
        return uuid;
    }

    @Override
    public Object getCredentials() {
        return uuid;
    }
}

5..2 realm

package com.itqq.realm;

import com.itqq.service.PermissionService;
import com.itqq.service.RoleService;
import com.itqq.shiro.UUIDToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author:syq
 * @Description:
 */
@Component
@Slf4j
public class UUIDRealm extends AuthorizingRealm {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;

    //用于判断传入的AuthenticationToken对象是否是UUIDToken的实例。如果是,则返回true,表示支持该令牌;否则返回false,表示不支持该令牌。
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UUIDToken;
    }
//    该函数调用了roleService.findRoleNameByEmployeeId(id)方法,
//    将返回值添加到info对象的roles属性中。
//    findRoleNameByEmployeeId方法根据员工ID查找对应的职位名称
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Integer id = (Integer) principalCollection.getPrimaryPrincipal();
        log.info("id:{}",id);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roleService.findRoleNameByEmployeeId(id));
        info.addStringPermissions(permissionService.findPermissionNameByEmployeeId(id));
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//          从令牌中提取UUID作为凭证
        String uuid = (String) token.getCredentials();
        if(!StringUtils.hasText(uuid)){
            throw new RuntimeException("token不能为空");
        }
//        从resdis中获取员工id
        Integer id = (Integer)redisTemplate.opsForValue().get(uuid);
        if(id == null){
            throw new RuntimeException("token已经失效");
        }
//        构建认证信息对象,包含用户ID、UUID和名称
//        将员工id,uuid(生成的),名称送去校验
        return new SimpleAuthenticationInfo(id,uuid,getName());
    }
}

                                                                                                                                                itqq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值