django-simple-sso实现单点登陆

django-simple-sso原始workflow

  1. User wants to log into a Client by clicking a “Login” button. The initially requested URL can be passed using the next GET parameter.
  2. The Client’s Python code does a HTTP request to the Server to request a authentication token, this is called the Request Token Request.
  3. The Server returns a Request Token.
  4. The Client redirects the User to a view on the Server using the Request Token, this is the Authorization Request.
  5. If the user is not logged in the the Server, they are prompted to log in.
  6. The user is redirected to the Client including the Request Token and a Auth Token, this is the Authentication Request.
  7. The Client’s Python code does a HTTP request to the Server to verify the Auth Token, this is called the Auth Token Verification Request.
  8. If the Auth Token is valid, the Server returns a serialized Django User object.
  9. The Client logs the user in using the Django User recieved from the Server.

前后端分离项目使用django-simple-sso的验证过程

image.png
  1. 用户请求前端页面,前端页面请求get_user_info接口,session有效可以返回用户信息。
  2. 当无法获取用户信息时,说明client端登陆失效。调用client端登陆接口。此接口会向server端获取request-token。server端会保存此token到token表中。
  3. user被重定向到server端的authorize接口,参数request-token。验证server端session是否有效,
"GET /server/authorize/?token=adpvzavQValZBGCzpGJE2QpnRQxNJVlWpQJ4h0uP8d2CuK0P7tBGuBXbUuyBqQyT HTTP/1.1" 302 0
  1. 无效则重定向到登陆页面,登陆后再次请求authorize接口。
  2. 有效则重定向到client端authenticate接口。此接口会向server端请求用户信息,并且请用户信息保存在client端的auth_user表中

部分代码

因为要实现不同域名之间的跳转,所以覆盖了原代码中的get_next方法,不进行任何安全限制。

class ClientLoginView(client.LoginView):
    def get_next(self):
        return self.request.GET.get('next', None)  # 允许跳转到外部域

class ClientAuthenticateView(client.AuthenticateView):

    def get(self, request):
        raw_access_token = request.GET['access_token']
        access_token = URLSafeTimedSerializer(self.client.private_key).loads(raw_access_token)
        user = self.client.get_user(access_token)
        user.backend = self.client.backend
        login(request, user)
        next = self.get_next()
        return HttpResponseRedirect(next)

    def get_next(self):
        return self.request.GET.get('next', None)  # 允许跳转到外部域

你可能感兴趣的:(django-simple-sso实现单点登陆)