赞
踩
本博客基于SpringBoot,使用redis缓存实现token认证,来验证用户身份的合法性。
token意为令牌,为一个随机的字符串UUID生成,用来标记来访用户的身份,通过该token,可以得出是哪一个用户向我服务器访问资源。
当用户登录成功之后,则向客户端发送token,用来标记该用户,以后每次用户向服务器访问时,则在请求头带上该token。服务器从请求头中获取token,拿到该token之后,向redis缓存查找是否存在此token,如存在,则返回给用户相应的资源,若不存在,则返回,不给与资源。
1.引入Maven依赖
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.21.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.chen</groupId>
- <artifactId>cachetest</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>cachetest</name>
- <description>Demo project for Spring Boot</description>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-test</artifactId>
- <version>2.1.6.RELEASE</version>
- <scope>test</scope>
- </dependency>
- <!-- 配置使用redis启动器 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <!-- 集成lombok简化代码 -->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <!--将对象转为json字符串-->
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>

2.创建user表
3.编写application.properties
- #配置数据源
- spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
- spring.datasource.username=root
- spring.datasource.password=123456
-
- #开启驼峰命名
- mybatis.configuration.map-underscore-to-camel-case=true
-
- #配置redis
- spring.redis.host=localhost
- spring.redis.port=6379
-
- #打印SQL语句日志
- logging.level.com.chen.mapper=debug
4.编写用户类User
- package com.chen.bean;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class User {
- int id;
- String username;
- String password;
- }
5.编写Mapper
- package com.chen.mapper;
-
-
- import com.chen.bean.User;
- import org.apache.ibatis.annotations.Mapper;
- import org.apache.ibatis.annotations.Select;
-
- @Mapper
- public interface UserMapper {
-
- @Select("SELECT * FROM `user` WHERE username=#{username} AND password=#{password}")
- public User getUser(User user);
- }
6.编写Service
- package com.chen.service;
-
- import com.chen.bean.User;
- import com.chen.mapper.UserMapper;
- import org.springframework.stereotype.Service;
-
- import javax.annotation.Resource;
-
-
- @Service
- public class UserService {
-
- @Resource
- private UserMapper userMapper;
-
- public User getUser(User user) {
- User u = userMapper.getUser(user);
- return u;
- }
- }

7.编写Msg类,用来封装返回的信息
- package com.chen.util;
-
- import java.util.HashMap;
- import java.util.Map;
-
- public class Msg {
-
- // 状态码: 200-成功 400-失败 500-异常
- private int status;
- // 提示信息
- private String message;
-
- // 用户返回给浏览器的数据
- private Map<String, Object> data = new HashMap<String, Object>();
-
- public static Msg success() {
- Msg result = new Msg();
- result.setStatus(200);
- result.setMessage("处理成功!");
- return result;
- }
-
- public static Msg fail() {
- Msg result = new Msg();
- result.setStatus(400);
- result.setMessage("处理失败!");
- return result;
- }
-
- public static Msg error() {
- Msg result = new Msg();
- result.setStatus(500);
- result.setMessage("未知异常!");
- return result;
- }
-
- public Msg add(String key, Object value) {
- this.data.put(key, value);
- return this;
- }
-
- public int getStatus() {
- return status;
- }
-
- public void setStatus(int status) {
- this.status = status;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public Map<String, Object> getData() {
- return data;
- }
-
- public void setData(Map<String, Object> data) {
- this.data = data;
- }
- }

8.编写Controller
- package com.chen.controller;
-
-
- import com.chen.bean.User;
- import com.chen.service.UserService;
- import com.chen.util.Msg;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.UUID;
- import java.util.concurrent.TimeUnit;
-
- @RestController
- public class UserController {
-
- @Autowired
- private StringRedisTemplate stringRedisTemplate;
-
- @Autowired
- private UserService userService;
-
- @PostMapping("/login")
- public Msg login(User user) {
- User u = userService.getUser(user);
- if (u != null) {
- String token = UUID.randomUUID().toString().replaceAll("-", "");
- stringRedisTemplate.opsForValue().set(token, String.valueOf(u.getId()), 3600, TimeUnit.SECONDS);//将用户的ID信息存入redis缓存,并设置一小时的过期时间
- return Msg.success().add("token",token).add("info","登录成功");
- }else {
- return Msg.fail().add("info", "登录失败");
- }
- }
-
- @PostMapping("/other")
- public Msg other() {
- return Msg.success().add("info", "该接口是来测试的");
- }
-
- }

9.配置启动类,使mapper生效
- package com.chen;
-
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cache.annotation.EnableCaching;
-
- @MapperScan("com.chen.mapper")
- @SpringBootApplication
- @EnableCaching
- public class CachetestApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(CachetestApplication.class, args);
- }
-
- }

10.设置拦截器,在进行接口访问前,先验证token的正确性
- package com.chen.interceptor;
-
- import com.chen.util.Msg;
- import org.json.JSONObject;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
-
- @Component
- public class ParamInterceptor implements HandlerInterceptor {
-
-
- @Autowired
- private StringRedisTemplate stringRedisTemplate;
-
- @Override
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
- String token = httpServletRequest.getHeader("token");
- //token验证
- if(token!=null){
- String id = stringRedisTemplate.opsForValue().get(token);
- if(id!=null){
- System.out.println("token验证成功");
- return true;
- }else{
- System.out.println("token验证失败");
- returnJson(httpServletResponse);
- return false;
- }
- }else{
- System.out.println("token验证失败");
- returnJson(httpServletResponse);
- return false;
- }
-
- }
-
- private void returnJson(HttpServletResponse response){
- PrintWriter writer = null;
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json; charset=utf-8");
- try {
- writer = response.getWriter();
- Msg msg = Msg.fail().add("info", "没有token或token无效");
- JSONObject jsonObject = new JSONObject(msg);
- writer.print(jsonObject);
- } catch (IOException e){
- e.printStackTrace();
- } finally {
- if(writer != null){
- writer.close();
- }
- }
- }
-
-
- @Override
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
-
- }
-
- @Override
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
-
- }
-
- }

11.配置拦截器,使前一步设置的拦截器生效
- package com.chen.config;
-
- import com.chen.interceptor.ParamInterceptor;
- 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.WebMvcConfigurationSupport;
-
- @Configuration
- public class InterceptorConfig extends WebMvcConfigurationSupport {
-
- @Autowired
- private ParamInterceptor paramInterceptor;
-
- public void addInterceptors(InterceptorRegistry registry) {
- //此处配置拦截路径
- registry.addInterceptor(paramInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
- }
-
- }

登录之后的结果:
使用其他接口进行测试:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。