最近在構思一件事情,使用spring-boot + spring-security+oauth實現受權的demo;
要測試,動手敲代碼最實際,可是,思考也是不能少的,不然也只是複製粘貼代碼。php
測試oauth的第一步,確定是先弄明白怎麼請求受權服務器,怎麼拿到code再拿到token。
因此第一步是建立一個能使用的「client」。經過對比,微博開放平臺會相對簡單點,由於微信有環境的限制。java
在閱讀微博開放平臺的登陸受權接口時,發現要填寫一個受權的回調url。
那麼疑問就來了:
若是個人「client」應用是一個相似公衆號的
好比:有多個菜單,點擊跳到不一樣的頁面,而這些頁面都須要先登陸微博受權
限制:用戶點擊登陸受權以後,回調的url是同一個
結果:那無論點擊那個菜單,最後都是跳到回調的頁面,多個菜單就形同虛設了web
請注意,這裏不是分析如何受權登陸,而是受權成功時,如何跳到所點擊的入口(菜單)spring
假設(靜默受權,就是不須要用戶點擊確認):瀏覽器
過程:服務器
問題在於:最後一步,拿到code再拿到token後,如何跳到咱們所點擊的入口(菜單)微信
session存放咱們所點擊的入口(菜單),在接收code的回調接口中,在把用戶重定向到咱們所點擊的入口菜單。session
127.0.0.1 oauth.server.com 127.0.0.1 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"; } }
<?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
jsp
注意在測試兩個接口的中間,要完全關閉瀏覽器,不然拿到的session是沒變的
再來思考下session的過時和時效
session.setMaxInactiveInterval(2);
sleep(10);
因爲session都過時了,server才返回code,此時拿到的session天然沒有東西啦
若是真的是多個菜單的場景,會存在一種狀況:我點了一個菜單,退出來,再點第二個菜單,session存的入口菜單就會覆蓋,這種狀況會不會有問題?
分析:不一樣時刻關閉從新點擊菜單,形成的影響會有點點不同若是咱們在拿到token以後,在session裏存放用戶的標誌字段,在其餘入口地址根據是否存在用戶的標誌字段來判斷是否須要從新認證,就沒問題了。