Session神奇的過時

初衷&緣起

最近在構思一件事情,使用spring-boot + spring-security+oauth實現受權的demo;
要測試,動手敲代碼最實際,可是,思考也是不能少的,不然也只是複製粘貼代碼。php

測試oauth的第一步,確定是先弄明白怎麼請求受權服務器,怎麼拿到code再拿到token。
因此第一步是建立一個能使用的「client」。經過對比,微博開放平臺會相對簡單點,由於微信有環境的限制。java

在閱讀微博開放平臺的登陸受權接口時,發現要填寫一個受權的回調url。
那麼疑問就來了:
若是個人「client」應用是一個相似公衆號的
好比:有多個菜單,點擊跳到不一樣的頁面,而這些頁面都須要先登陸微博受權
限制:用戶點擊登陸受權以後,回調的url是同一個
結果:那無論點擊那個菜單,最後都是跳到回調的頁面,多個菜單就形同虛設了web

請求過程分析

請注意,這裏不是分析如何受權登陸,而是受權成功時,如何跳到所點擊的入口(菜單)spring

假設(靜默受權,就是不須要用戶點擊確認):瀏覽器

  • 咱們的應用(client)的域名是:web.client.com
  • client中有一個菜單是:web.client.com/ha
  • client中有個回調地址:web.client.com/receive
  • 微博開發平臺的域名是:oauth.server.com
  • 微博確認受權接口地址是:oauth.server.com/test

過程:服務器

  • 訪問client的任意菜單(web.client.com/ha)
  • client發現須要登陸微博受權,將用戶重定向到oauth.server.com/test
  • 微博確認了用戶信息,把用戶重定向到web.client.com/receive,並帶上code
  • client接收到code,而且能夠經過code拿到token並暫存。

問題在於:最後一步,拿到code再拿到token後,如何跳到咱們所點擊的入口(菜單)微信

猜想&實驗:session可否實現?

猜想思路

session存放咱們所點擊的入口(菜單),在接收code的回調接口中,在把用戶重定向到咱們所點擊的入口菜單。session

實驗代碼

host配置兩個站點

127.0.0.1 oauth.server.com
127.0.0.1 web.client.com

web.client.com接口

package com.lgh.demo.controller;

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

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

@Controller
public class IndexController {

    @RequestMapping("/ha")
    public String index(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        System.out.println("/ha 請求,redirect:http://oauth.server.com/test");
        System.out.println(session.getId());
        System.out.println(request.getRequestURL());
        session.setAttribute("entrance", request.getRequestURL());
        return "redirect:http://oauth.server.com/test";
    }

    @RequestMapping("ha2")
    public String index2(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
        System.out.println("/ha2 請求,redirect:http://oauth.server.com/test");
        System.out.println(session.getId());
        System.out.println(request.getRequestURL());
        session.setAttribute("entrance", request.getRequestURL());
        return "redirect:http://oauth.server.com/test";
    }

    @RequestMapping("/receive")
    public String receive(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        System.out.println("/receive請求, 返回haha.jsp");
        System.out.println(session.getId());
        System.out.println("code = " + request.getParameter("code"));
        System.out.println("入口地址:" + session.getAttribute("entrance"));
        return "haha";
    }
}

oauth.server.com接口(php)

<?php
session_start();
$code = rand(10000, 99999);
header("Location: http://web.client.com:8080/receive?code=$code");
exit;
?>

實驗結果

第一次:web.client.com:8080/ha
圖片描述app

第二次:web.client.com:8080/ha2
clipboard.pngjsp

注意在測試兩個接口的中間,要完全關閉瀏覽器,不然拿到的session是沒變的

再來思考下session的過時和時效

  • 過時:通常會有默認的過時時間,是由服務器的默認配置的。
  • 失效:通常都是瀏覽會話結束時失效(瀏覽會話結束是指:瀏覽器完全關掉全部的tab,一個不留,有一個沒關,瀏覽會話都沒結束)

腦殘測試

條件

  • 把client的兩個接口都設置session的過時時間:session.setMaxInactiveInterval(2);
  • server接口中,添加睡眠代碼:sleep(10);

結果

因爲session都過時了,server才返回code,此時拿到的session天然沒有東西啦
clipboard.png

延伸思考:

屢次訪問不一樣入口

若是真的是多個菜單的場景,會存在一種狀況:我點了一個菜單,退出來,再點第二個菜單,session存的入口菜單就會覆蓋,這種狀況會不會有問題?

分析:不一樣時刻關閉從新點擊菜單,形成的影響會有點點不同若是咱們在拿到token以後,在session裏存放用戶的標誌字段,在其餘入口地址根據是否存在用戶的標誌字段來判斷是否須要從新認證,就沒問題了。

相關文章
相關標籤/搜索