Azard / egg-oauth2-server

:star2: OAuth2 server plugin for egg.js based on node-oauth2-server
MIT License
179 stars 45 forks source link

有关client grants属性的问题 #46

Open zhuqiming opened 5 years ago

zhuqiming commented 5 years ago

您好: 想请教一下 AuthorizeHandler.prototype.getClient = function(request) { var clientId = request.body.client_id || request.query.client_id;

if (!clientId) { throw new InvalidRequestError('Missing parameter: client_id'); }

if (!is.vschar(clientId)) { throw new InvalidRequestError('Invalid parameter: client_id'); }

var redirectUri = request.body.redirect_uri || request.query.redirect_uri;

if (redirectUri && !is.uri(redirectUri)) { throw new InvalidRequestError('Invalid request: redirect_uri is not a valid URI'); } return promisify(this.model.getClient, 2).call(this.model, clientId, null) .then(function(client) { if (!client) { throw new InvalidClientError('Invalid client: client credentials are invalid'); }

  if (!client.grants) {
    throw new InvalidClientError('Invalid client: missing client `grants`');
  }

  if (!_.includes(client.grants, 'authorization_code')) {
    throw new UnauthorizedClientError('Unauthorized client: `grant_type` is invalid');
  }

  if (!client.redirectUris || 0 === client.redirectUris.length) {
    throw new InvalidClientError('Invalid client: missing client `redirectUri`');
  }

  if (redirectUri && !_.includes(client.redirectUris, redirectUri)) {
    throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
  }
  return client;
});

}; 在鉴权第一步的时候,首先会调用getClient方法获取我们注册的app信息,这里会验证grants这个属性,我不太理解这个属性到底有什么含义,或者说是他的意义体现在哪里? 因为我现在也在做一个鉴权的服务,其中应用信息是另一个项目进行创建注册的,在创建应用的时候,grants这个属性现在是必须要的,而且值也是固定的几个值,就是不太理解为什么要验证这个属性

Azard commented 5 years ago

这个项目的 grants 是 oauth2 模式类型的意思,就是 constant 常量。如果要扩展一些自定义鉴权流程的话还是有点意义的。

zhuqiming commented 5 years ago

好的,谢谢哈,因为平时都是使用github或者企业微信这种已有的鉴权服务,现在是自己搭建一个鉴权服务,逻辑有时候没整明白,我记得像是github的话,如果我的电脑登陆的github账户,则需要用github鉴权的时候,他会跳转到一个页面问我是否授权,如果我电脑没有登陆的话,就会跳转到一个登陆页面,我输入github的账户登陆就是授权了,如果是上述情况的话,我用现在的这个插件搭建的鉴权服务,应该是走哪几个方法呢?? 我现在采用的是authorization_code方法,定义了三个路由 // 用户认证 router.all('/qimo/user/authorize', app.oAuth2Server.authorize(), controller.auth.apis.userOauth.getCode); // 获取token router.all('/qimo/user/getToken', app.oAuth2Server.token(), controller.auth.apis.userOauth.getToken); // 验证token router.all('/qimo/user/authenticate', app.oAuth2Server.authenticate(), controller.auth.apis.userOauth.authenticate); 我看README里面写的首先是调用authorize这个方法,他会依次调用getClient、getUser,如果是上面刚刚说的,输入用户密码点击登陆,走的是这个顺序,是没问题,如果是跳转到那种不输入用户密码的页面,直接点击授权的,是不是没有走这个方法呀?走的话我也获取不到user信息呀,有点懵。。。

Azard commented 5 years ago

输入用户名密码是 password 模式,已经登录了的话可以用授权码模式,授权只信任第三方系统不自己验证。可以看看 oauth2 几种类型:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

zhuqiming commented 5 years ago

好的,这篇文章我看过了,里面的类型我也了解了,我是想模拟一下github的认证机制,举个例子:就是如果我的电脑没有登陆github这个网站,那么我的第三方应用在申请授权的时候(访问这个链接:"https://github.com/login/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A7001%2Fauth&client_id=6a980e357ab14a87350e"),则此时,页面会重定向到github的登陆页面,我看了是根据括号里面的那个地址的response的location字段跳转的登陆页面,此时我输入用户名和密码,点击登陆,这之后的流程就和我现在用这个插件实现的流程一致了:getClient->getUser->saveAuthorizationCode一次调用,返回code 如果我电脑登陆了GitHub网站,此时第三方应用申请授权的时候,访问的还是上面括号里面的链接,然后就没有输入密码的那个界面了,就直接进入我的第三方系统界面了,并且获取了用户信息 我就是不太清楚这个过程中,github他是如何得知用户是否登陆的,因为访问的都是同一个认证地址??

rise0chen commented 5 years ago

应该是使用cookies或者storage记录登录状态