1. 程式人生 > >spring boot 使用redis 管理用戶會員登錄

spring boot 使用redis 管理用戶會員登錄

login 失效 registry .com 一個 div 平臺 inb jca

使用場景

現在很多基於restful的api接口都有個登錄的設計,也就是在發起正式的請求之前先通過一個登錄的請求接口,申請一個叫做token的東西。申請成功後,後面其他的支付請求都要帶上這個token,服務端通過這個token驗證請求的合法性。這個token通常都有一個有效期,一般就是幾個小時。

在比如微信的公眾平臺接口,關鍵的接口在使用之前都要帶access token。access_token是公眾號的全局唯一票據,有效期為7200秒,重復獲取將導致上次獲取的access_token失效。

Redis的安裝配置 (docker)

 docker pull redis
 docker run --name redis -d -p 6379:6379 redis:latest

springboot項目

1.在新建項目的時候,選擇redis相關依賴

2.在application.yml (這裏使用yml) 配置redis參數

spring:
  redis:
    host: 192.168.147.129
    port: 6379

3.redis常數實體類

package com.example.demo.bean;

/**
 * Created by Administrator on 2017/12/11 0011.
 */
public interface RedisConstant {

    String TOKEN_PREFIX = "token_%s";
    //2小時
    Integer EXPIRE = 60;
}

4.配置登錄的攔截器

配置類

package com.example.demo.config;

import com.example.demo.util.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * Demo class
 *
 * @author aslan
 * @date 2017/12/12
 */
@Configuration
public class LoginInterceptor extends WebMvcConfigurerAdapter{

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

實現類:

package com.example.demo.util;

import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import com.example.demo.bean.RedisConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jca.context.SpringContextResourceAdapter;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * Demo class
 *
 * @author aslan
 * @date 2017/12/12
 */
public class MyInterceptor implements HandlerInterceptor{


    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("pre hander");
        //判斷該用戶是否已登錄,如果沒有登錄,跳轉到登錄界面

        //獲取token
        Cookie[] cookies =    httpServletRequest.getCookies();
        String token =null;
        for (Cookie cookie: cookies) {
            if ("token".equals(cookie.getName())) {
                token = cookie.getValue();
                break;
            }
        }

        //redisTemplate
        ServletContext context = httpServletRequest.getServletContext();
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
        StringRedisTemplate redisTemplate  = ctx.getBean(StringRedisTemplate.class);

        //從redis中檢查該token是否存在
        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, token));
        if (StringUtils.isEmpty(tokenValue)) {
            System.out.println("【登錄校驗】Redis中查不到token");
            return false;
        }else {
            System.out.println("get token " + tokenValue);
            return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println(" post hander");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("after ");
    }
}

5.登錄Controller

package com.example.demo.controller;

import com.example.demo.bean.RedisConstant;
import com.sun.deploy.net.HttpRequest;
import com.sun.deploy.net.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * Created by Administrator on 2017/12/11 0011.
 */

@RestController
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/")
    public String index(){
        return "aha";
    }

    @RequestMapping(value = "/loginbypost", method = RequestMethod.POST)
    public String loginByPost(@RequestParam(value = "name", required = true) String name,
                              @RequestParam(value = "pwd", required = true) String pwd,
                              HttpServletResponse response) {

        //生成token
        String token = UUID.randomUUID().toString();
        // 設置token到cookie裏面
        Cookie cookie = new Cookie("token",token);
        cookie.setPath("/");
        cookie.setMaxAge(7200);
        response.addCookie(cookie);
        return null;
    }

    @RequestMapping(value = "/loginbyget", method = RequestMethod.GET)
    public String loginByGet(@RequestParam(value = "name", required = true) String name,
                             @RequestParam(value = "pwd", required = true) String pwd,
                             HttpServletResponse response) {
        //生成token
        String token = UUID.randomUUID().toString();
        Integer expire = RedisConstant.EXPIRE;

        redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX, token), "didididi", expire, TimeUnit.SECONDS);

        // 設置token到cookie裏面
        Cookie cookie = new Cookie("token",token);
        cookie.setPath("/");
        cookie.setMaxAge(120);
        response.addCookie(cookie);
        return "login success";
    }

    @RequestMapping(value = "/getit",method = RequestMethod.GET)
    public String getit(HttpServletRequest request){

        Cookie[] cookies =    request.getCookies();
        String token =null;
        for (Cookie cookie: cookies) {
            if ("token".equals(cookie.getName())) {
                token = cookie.getValue();
                break;
            }
        }

        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, token));
        if (StringUtils.isEmpty(tokenValue)) {
            System.out.println("【登錄校驗】Redis中查不到token");
        }else {
            System.out.println("get token " + token);
        }

        return  null;
    }
}

6.測試Controller

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Demo class
 *
 * @author aslan
 * @date 2017/12/12
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/getone")
    public String getone(){
        return "in 3 getone";
    }


    @RequestMapping("/gettwo")
    public String gettwo(){
        return "in 3 gettwo";
    }

    @RequestMapping("/getthree")
    public String getthree(){
        return "in 3 getthree";
    }
}

7.測試方法

nginx做負載均衡
技術分享圖片

spring boot 使用redis 管理用戶會員登錄