Spring Boot and OAuth2 Tutorials 的一个问题

https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_click

最近在做这个Tutorial, 基本是OAuth2典型的登录流程:
1.用户在自己网站的网页上点击“Login Using FaceBook”后跳转到FaceBook(OAuth2 Auth Server)进行认证
2.到Auth Server的授权页面进行授权
3.到自己网站的某URL触发AccessToken的Exchange
4.获取AccessToken成功后回到初始页面。

因为有自己的技术栈,所以并没有采用官方的AngularJS做前端,我就简单的用了Fetch+JQuery,结果出现以下问题:
OAuth2 Auth Server(我用的自己写的server,不是FB)登录成功后,浏览器并没有跳转回localhost/页面,而是跳转到了localhost/user的页面,尽管登录成功了,但是这个landing page是有问题的。

跟了一下源码,记录几个知识点:
1.在OAuth2SsoProperties类中定义了DEFAULT_LOGIN_PATH,为"/login",这个URL用于步骤3,是负责跟Auth server交换Token的URL,OAuth2流程中有个Return URI的概念,就是Auth Server在认证成功后要把你重定向到哪里的URL。

2.在/login的业务逻辑做完之后,该把用户重定向到哪里呢? 当然应该重定向到用户"上一次访问"的页面。这个"上一次访问"的页面是怎么定义的?是在ExceptionTranslationFilter(这个Filter的功能请自己补充下知识)中触发的,最终调用了HttpSessionRequestCache.saveRequest(),储存了一个requestCache。也就是说,如果你访问的页面不是一个受到保护的页面,Spring是不会保存这个request Cache的。 当然了,Spring也提供了其他重定向策略,比如可以一直重定向到一个固定页面。

3. 从2可以看到,其实最终登录成功要回到哪个页面,已经在你点击"login using XXX"这个按钮时就已经决定了,应该是你在点这个按钮之前访问的最后一个受保护的页面。那为什么官方文档能回到"/主页",我却只能回到"/user"这个页面呢?而且从流程来看,/user这个API是都要调用的,所以/user才是本来应该的landing page,气氛上我的结果反而是对的。。。
继续跟到源码看官方文档的那个例子HttpSessionRequestCache.saveRequest()这个方法为什么没把/user的访问记录给存下来,发现在做方法的第一行
requestMatcher.matches(request)

时候,代理到了MediaTypeRequestMatcher这个类,原因也没往细看,主要的区别在于官方用Angular的话在request中添加了Accept的header,而我在用Fetch时候是没这个Header的。

于是加上Accept:application/json,问题解决。

这种坑真是防不胜防。尽管现在Spring Boot让一切都看起来简单了,遇到坑的时候就能体会到这种便利是有代价的。。。

猜你喜欢

转载自wwwcomy.iteye.com/blog/2392525