postman怎么传session_十几行代码实现分布式 Session

32fb5b93fd0f6ce8b19073003848e4fc.png

前言

最近喊同事吃饭的时候他在测接口,于是我就在他后面等了一会。他测的是一个需要登录的接口,步骤如下

1.先登录系统从接口的request head中拿到cookie的值

2.把这个cookie的值粘到postman请求的header中

3.发送请求测试接口

我发一张图,你大概可以想到测的姿势

7f4f8589bd785cf967b9186e8259f9f9.png

说真的,这波操作真的秀到我了,于是我把我的骚操作告诉了他,如果大家也没用过这种方式的话,可否在下面评论一句学到了,我看看不会用的人多不。

6abd5d07c314cd15cd9db5cb07f8d619.gif

写登录例子的时候我又觉得文章太短不好,嗯,太短不好。于是在前面分享一下分布式session的实现吧。分布式session在企业中基本上都会用到。因为登录系统不可能只有一个,所以要在2个系统间共享session。我写个demo,总共也就十几行代码,足够帮你理解怎么实现分布式session了。

6a61fac04f4ed7a34add64a98e902c80.png

十几行代码实现分布式session

请求controller

@RestController@RequestMapping("user")public class UserAuthController {    // 1 hour    private static final int TOKEN_EXPIRE_SECONDS = 1 * 60 * 60;    private static final String COOKIE_NAME = "FL";    @RequestMapping("login")    public ServerResponse login(HttpServletResponse response) {        // 这里的cookie值我随便写了一个字符串"token"        // 生产环境中token有一套复杂的生成规则,例如MD5(用户名+登陆ip+当前时间)后的字符串        // 登录的时候我们先根据输入的用户名拿到用户信息        // 然后把 token->用户信息 的映射关系放到redis中,或者mysql中        Cookie cookie = new Cookie(COOKIE_NAME, "token");        // 设置cookie的过期时间为1个小时,即1个小时内你都不用重新登陆        cookie.setMaxAge(TOKEN_EXPIRE_SECONDS);        response.addCookie(cookie);        return ServerResponse.success();    }    @RequestMapping("cart")    public ServerResponse cart() {        return ServerResponse.success();    }}

可以看到我写了2个接口,一个登陆接口,一个访问购物车接口,ServerResponse是我定义的返回对象,其中访问购物车接口需要登陆,我在拦截器中做了校验

整个登陆过程做的是其实很简单,生成一个cookie,名字为FL,值为字符串"token",(生产环境中token有一套复杂的生成规则,例如MD5(用户名+登陆ip+当前时间)后的字符串)放在reponse中,并把token->用户信息的映射关系放在redis中或者mysql中

放在redis中你可以使用命令

setnx token 用户信息 1h

来保存映射关系。用mysql你可以用用户表来保存映射关系

idtokentokenExpire用户idtoken值token的失效时间

当然token的失效时间和cookie的失效时间保持一致,失效时间可以用

System.currentTimeMillis()+1h算出

登陆校验拦截器

public class LoginInterceptor extends HandlerInterceptorAdapter {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        Cookie cks [] = request.getCookies();        if (cks == null || cks.length == 0) {            this.processError(response);            return false;        }        // 这里cookie的名字在UserAuthController里面定义了        String cookieName = "FL";        String token = null;        for (Cookie ck : cks) {            if (cookieName.equals(ck.getName())) {                token = ck.getValue();                break;            }        }        if (token == null) {            this.processError(response);            return false;        }        // 在登录的时候我们设置了 token-> 用户信息 的映射关系        // 根据token从redis或者mysql中拿到用户信息,然后设置到requst请求中,供后续请求使用        // 分布式session就这样实现了        request.setAttribute("userInfo", null);        return true;    }    private void processError(HttpServletResponse response) throws IOException {        response.reset();        response.setContentType("application/json;charset=UTF-8");        response.setCharacterEncoding("utf-8");        response.getWriter().write("请登录");    }}

上述代码我没做失效时间的验证,简单说一下。

如果用的是redis,根据token拿不到用户信息,说明登录信息已经失效了。

用的是mysql,只要判断请求时间是否在token失效时间内,如果不在token失效时间内,则用户需要重新登录。

配置拦截器

@Configurationpublic class DemoWebMvcConfigurerAdapter extends WebMvcConfigurationSupport {    @Override    protected void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login");    }}

单机session,例如tomcat是把 token->用户 的映射关系放在ConcurrentHashMap中

而分布式session是要我们自己维护这个映射关系,并且多个实例都能访问到这个映射关系。

测试验证

我直接访问

http://127.0.0.1:8081/user/cart

页面 显示请登录先访问

http://127.0.0.1:8081/user/login

再访问

http://127.0.0.1:8081/user/cart

正常返回

如下内容

{    "status": 0,    "msg": "success"}

访问http://127.0.0.1:8081/user/login Reponse Headers为

Content-Type: application/json;charset=UTF-8Date: Wed, 25 Dec 2019 12:18:03 GMTSet-Cookie: FL=token; Max-Age=3600; Expires=Wed, 25-Dec-2019 13:18:03 GMTTransfer-Encoding: chunked

可以看到设置了cookie(FL=token)

再访问http://127.0.0.1:8081/user/cart Request Headers为

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cache-Control: max-age=0Connection: keep-aliveCookie: FL=token

可以看到带上了cookie(FL=token)

秒测登录接口

这个操作其实太简单了,在postman中,你只要先请求一下登录接口,在后续请求的接口中会自动带上cookie,不用你每次都粘header。在cookie失效之前你都不用再次点登录接口,一直测就行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值