最近在项目中需要在后端项目中接入sso系统和权限系统。之前在学习Java时其实也学习过,过了一个寒假就什么都不记得了。
SSO接入
现在sso系统已经很强大,前端完成主要功能,而后端实现对应的接口api/login
和api/logout
即可实现前后端的接入。这里只记录基本的逻辑顺序
- 前端打开页面时,前端框架自动调用
sso
系统,执行登录操作 sso
登录成功后,前端会调用后端的login
接口,传入从前端获得的service
和ticket
login
函数会以service
和ticket
,再次向sso
系统接口执行一次服务登录校验- 校验成功,接口会传回登录用户的信息,包装成UserInfo的结构体
login
函数生成一个随机值作为sessionId
,将UserInfo
序列化为json
串,- 接下来这里有两种处理方式,一种是将用户信息缓存到
redis
中,即sessionId=session
,另一种是将用户Json
串执行对称加密转换为token
,这两种处理的结果最终都保存到控制器的cookie
中,即c.Ctx.SetCookie
- 向其他接口发送操作时,都需要判断一下是否是已登录
路由注册时,采用NSBefore
提供一个前置过滤器
beego.NSBefore(auth.CheckSSO),
beego.NSNamespace("/login",
beego.NSInclude(
&sso.LoginController{},
),
),
这样所有的请求进来后都会执行一下这个过滤器。简单梳理一下这个过滤器的执行过程。
8. CheckSSO. 获得当前请求的URL路径,根据URL路径不同可以采用不同的操作,比如对于login这个api可以不用要求必须登录。
9. 从Cookie中拿到sessionId和token,根据这两个参数可以从redis中读取或者是解密出用户信息,拿到userInfo。如果拿到的用户信息为空,说明没有登录,则返回错误信息,前端跳转到登录界面。如果拿到用户信息,则保存到context中,供后面操作中使用。
func CheckSSO(ctx *context.Context) {
urlPath := ctx.Input.Context.Request.URL.Path
sessionId := ctx.GetCookie(constants.SessionIdName)
accessToken := ctx.GetCookie(constants.AccessTokenName)
user, _ := GetUserInfo(sessionId, accessToken)
..........
根据URL和user信息进行分别处理
..........
}
}
权限系统接入
这里的权限系统是一个公共的系统,对外提供接口,在系统中创建资源后,设置不同的成员的角色,包括master,developer,guest,这些角色对应不同的权限,可以自己进行设置。权限系统提供的是http接口,只要将系统,人员信息,资源信息等以http请求的方式发送到权限系统,能够返回对应的角色,从而执行权限设置。总的来说还是比较方便的,这里就主要分享一下做法。
反思
以上开发的功能模块其实都是整合现有的系统,难度绝对算不上难。但是实际编写代码时还是会出很多错,主要的问题还是自己编码的规范性和合理性。在编码时考虑接口的使用场景,未来拓展等,以及减少调用函数时的重复操作,尽量实现起来简洁优雅,这些都是以后要慢慢学习,在实际开发中一直注意的。