简单说一下个人逻辑,我也不知道我理解sso对不对。php
假如三个站点 a.baidu.com b.baidu.com c.baidu.comjson
a.baidu.com 做为验证用户登陆帐户。
b和c做为客户端(子系统)。缓存
b和c须要登陆的时候跳转到a,而且携带参数source指明登录后跳转的连接。安全
a站点就是普通的登录方式(校验用户密码),校验成功后作一些处理。须要生成一个ticket,具体怎么生成均可以,只要安全就能够了。而后存储到Cache里面。这里有疑问,后面总结。登录成功后直接跳转到$url就能够了。session
private function getTicketUrl($source) { $ticket = md5(time()+key); Cache::put($ticket, $user, 120); $url = $source . '?ticket=' . $ticket; return $url; }
假如说a站带着ticket跳转到b站(b.baidu.com?ticket=xxxxxxxxxxxxxxxx
)并发
b站作一个全局的过滤器,接受这个ticket而后请求a站验证ticket是否为a生成的。ui
b站过滤器App\Http\Middleware\CasAuthenticate
代码,这里判断是否有ticket并发送请求到a站校验。若是是登录的,则拿到用户UID进行登录。url
public function handle($request, Closure $next) { $ticket = $request->input('ticket'); if ($ticket) { $result = json_decode('http://a.baidu.com' . '/auth/check-ticket?ticket=' . $ticket), true); if ($result['state'] == "SUCCESS") { $request->session()->flush(); Auth::loginUsingId($result['result']['uid']); return redirect(redirect()->getUrlGenerator()->current()); } } return $next($request); }
逻辑算是完成了,可是有几个疑问。code
1.我这个实现,我本身都不知道是否是对的,这是我根据原理写出来的。md5
2.假如b站如今跳转到c站,因为b站活跃比较频繁,session一直都在,而a站的缓存时间极有可能已通过期了,此时从b站跳转到c站,c站跳转到a站去判断登录,结果发现已经失效了,仍是得登录。因此这是有问题的,因为咱们业务模块相关性差,不会随意跳转,因此暂不考虑这样的问题。但这确实是个人一个问题。我没想清楚。
转载注明:罗志强的博客