springboot+redis实现token机制

token就是标志、记号的意思,在IT领域也叫做令牌。在前后端分离的项目中需要做登录的话,就需要使用token作为前后端唯一的凭证。

项目结构

pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>nl.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>
	</dependencies>

application.properties

##指定使用redis数据库索引(默认为0)
spring.redis.database=0
##指定Redis服务器地址
spring.redis.host=192.168.126.149
##指定Redis端口号
spring.redis.port=6379
##指定Redis密码
spring.redis.password=123456

User.java

package com.fengqing.aapredis.bean;

public class User {
    private Integer id;

    private String username;

    private String password;

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public User() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Dto.java

package com.fengqing.aapredis.bean;

public class Dto {

    private String token;

    private Long tokenCreatedDate;

    private Long tokenExpiryDate;

    private String isLogin;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public Long getTokenCreatedDate() {
        return tokenCreatedDate;
    }

    public void setTokenCreatedDate(Long tokenCreatedDate) {
        this.tokenCreatedDate = tokenCreatedDate;
    }

    public Long getTokenExpiryDate() {
        return tokenExpiryDate;
    }

    public void setTokenExpiryDate(Long tokenExpiryDate) {
        this.tokenExpiryDate = tokenExpiryDate;
    }

    public String getIsLogin() {
        return isLogin;
    }

    public void setIsLogin(String isLogin) {
        this.isLogin = isLogin;
    }
}

RedisUtil.java

package com.fengqing.aapredis.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public void set(String key, String value) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, value);
    }

    public void setex(String key, String value, int seconds) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, value, seconds);
    }
}

TokenService.java

package com.fengqing.aapredis.service;

import com.alibaba.fastjson.JSONObject;
import com.fengqing.aapredis.bean.User;
import com.fengqing.aapredis.util.RedisUtil;
import nl.bitwalker.useragentutils.UserAgent;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@Service("tokenService")
public class TokenService {

    @Resource
    private RedisUtil redisUtil;

    //生成token(格式为token:设备-加密的用户名-时间-六位随机数)
    public String generateToken(String userAgentStr, String username) {
        StringBuilder token = new StringBuilder("token:");
        //设备
        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentStr);
        if (userAgent.getOperatingSystem().isMobileDevice()) {
            token.append("MOBILE-");
        } else {
            token.append("PC-");
        }
        //加密的用户名
        token.append(DigestUtils.md5Hex(username) + "-");
        //时间
        token.append(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "-");
        //六位随机字符串
        token.append(new Random().nextInt(999999 - 111111 + 1) + 111111 );
        System.out.println("token-->" + token.toString());
        return token.toString();
    }

    //把token存到redis中
    public void save(String token, User user) {
        if (token.startsWith("token:PC")) {
            redisUtil.setex(token, JSONObject.toJSONString(user), 2*60*60);
        } else {
            redisUtil.set(token, JSONObject.toJSONString(user));
        }
    }

}

UserService.java

package com.fengqing.aapredis.service;

import com.fengqing.aapredis.bean.User;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserService {
    public User login(String username, String password) {
        if ("tom".equals(username) && "123".equals(password)){
            return new User(1, "tom", "123");
        } else {
            return null;
        }
    }
}

UserController.java

package com.fengqing.token.controller;

import com.fengqing.token.bean.Dto;
import com.fengqing.token.bean.User;
import com.fengqing.token.service.TokenService;
import com.fengqing.token.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    @GetMapping("/login")
    public Dto login(String username, String password, HttpServletRequest request){
        Dto dto = new Dto();
        User user = this.userService.login(username, password);
        if (user != null) { //成功
            String userAgentStr = request.getHeader("user-agent");
            //生成token
            String token = this.tokenService.generateToken(userAgentStr, username);
            //保存token
            this.tokenService.saveToken(token, user);
            //组织前台需要的信息
            dto.setToken(token);
            dto.setLogin("true");
            dto.setTokenCreateDate(System.currentTimeMillis());
            dto.setTokenExpireDate(System.currentTimeMillis() + 7200000);
        } else { //失败
            dto.setLogin("false");
        }
        return dto;
    }


}

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值