简体   繁体   English

如何将服务器端获得的SSO用户登录到Meteor Accounts包中?

[英]How do I sign-in a server-side acquired SSO user into the Meteor Accounts package?

Using Meteor , coffeescript and iron-router , I am successfully acquiring a user from a SAML Identity Provider (IdP). 通过使用Meteorcoffeescriptiron-router ,我成功地从SAML身份提供商(IdP)获得了用户。

How can I use these user details to sign-in the user via the Meteor Accounts package? 如何使用这些用户详细信息通过“流星帐户”包登录用户?

Consider the following server-side routes: 考虑以下服务器端路由:

Router.route '/sso/saml2', where: 'server', name:'ssoSaml'
    .get ->
        @response.writeHead 302, 'Location': saml.getRequestUrl()
        @response.end()
    .post ->
        {secret:{password, email}, profile, state} = saml.getProfile @request.body.SAMLResponse
        user= Meteor.users.findOne {'profile.domainId': profile.domainId}
        userId = if user? then user._id else Accounts.createUser {password, email, profile}
        # I have the user id - How do I sign the user in?
        @response.writeHead 302, 'Location': "#{state.location}"
        @response.end()

The process is as follows: 流程如下:

  • The GET route redirects the browser to the IdP end-point with an appropriately generated SAMLRequest . GET路由使用适当生成的SAMLRequest将浏览器重定向到IdP端点。
  • The IdP processes the SAMLRequest and returns a SAMLResponse to the POST route. 对IDP处理SAMLRequest并返回SAMLResponse到POST路线。
  • The SAMLResponse is processed returning the user's secret fields, public profile and a state object containing the originally requested location 处理SAMLResponse并返回用户的secret字段,公共profile和包含原始请求locationstate对象
  • The unique, immutable profile.domainId is used to retrieve the user from the Meteor user collection 唯一的,不变的profile.domainId用于从Meteor user集合中检索user
  • If no user exists a new one is created. 如果没有user ,则创建一个新user

At the end of this process I have the user details and I know the user exists in the Meteor.users collection. 在此过程结束时,我将获得用户详细信息,并且知道该用户存在于Meteor.users集合中。 To finish I need to sign-in the user and redirect to the originally requested location. 最后,我需要登录用户并重定向到最初请求的位置。

How do I sign-in the user? 如何登录用户?

Ultimately, the login call that sets the user must be made from client code. 最终,设置用户的登录调用必须从客户端代码进行。

  1. Define a collection for login tokens: 定义登录令牌的集合:

     @LoginTokens = new Mongo.Collection 'loginTokens' 
  2. Use your original server-side routes, but create a one-time login token for the client to use to log in, then redirect to a client route, passing the token. 使用原始的服务器端路由,但为客户端创建一次性登录令牌,以供客户端登录,然后重定向到客户端路由,并传递令牌。

     Router.route '/sso/saml2', where: 'server', name:'ssoSaml' .get -> @response.writeHead 302, 'Location': saml.getRequestUrl() @response.end() .post -> {secret:{password, email}, profile, state} = saml.getProfile @request.body.SAMLResponse user= Meteor.users.findOne {'profile.domainId': profile.domainId} userId = if user? then user?._id else Accounts.createUser {password, email, profile} tokenId = LoginTokens.insert { userId, expires: +(new Date)+tokenExpirationInMilliseconds } @response.writeHead 302, 'Location': "/sso/login/#{tokenId}?loc=#{state.location}" @response.end() 
  3. Register a custom login handler on the server accepting and validating a login token: 在服务器上注册一个自定义登录处理程序,以接受并验证登录令牌:

     Accounts.registerLoginHandler ({tokenId})-> {userId} = LoginTokens.findOne tokenId or {} return {userId} if userId? 
  4. Call this handler on the client in your client-side route that receives the login token, but make sure the arguments match this strange signature (notice the array): 在接收登录令牌的客户端路由中,在客户端上调用此处理程序,但请确保参数匹配此奇怪的签名(注意数组):

     Router.route '/sso/login/:tokenId', -> {tokenId, query} = @params Accounts.callLoginMethod methodArguments: [{tokenId}] userCallback: -> Router.go if query?.loc? then query.loc else '/' 
  5. Finally, create a job on the server that regularly clears expired tokens: 最后,在服务器上创建一个定期清除过期令牌的作业:

     Meteor.setInterval -> LoginTokens.remove { expires: { $lte: +(new Date) } } , 1000 

** Note: be sure to pass an object containing the login token as the element in the methodArguments array when calling your login method, Also, in the login handler, return an object with the userId property whose value is the user id for your user, in order to match the expected signatures. **注意:调用登录方法时,请确保传递一个包含登录令牌的对象作为methodArguments数组中的元素,此外,在登录处理程序中,返回一个带有userId属性的对象 ,该对象的值是用户的用户ID ,以匹配预期的签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM