使用github OAuth实现用户登录
做登录功能时,允许使用第三方网站的身份,这称为"第三方登录"。
原理
github内的认证方法
在github上申请OAuth App,进入个人的Github首页,Settings->Applications->Developer applications->Register a new application
注册这个app的目的:You can enable other users to authorize your OAuth App.
您可以让其他用户授权您的OAuth应用程序。
获取code和state
<a href="https://github.com/login/oauth/authorize?client_id=1d1f99e3efc33edcbf45&redirect_uri=http://localhost:8080/callback&scope=user&state=1">登陆</a>
scope
属性列出了用户授予的附加到令牌的范围。通常,这些范围将与您要求的范围相同。但是,用户可以编辑其范围,从而有效地授予您的应用程序比您最初请求的访问权限少的权限。此外,用户可以在OAuth流完成后编辑令牌作用域。您应该意识到这种可能性,并相应地调整应用程序的行为。
处理用户选择授予您的访问权限比您最初请求的权限少的错误情况非常重要。例如,应用程序可以警告其用户或以其他方式与其用户进行通信,告知他们功能将减少或无法执行某些操作。
此外,应用程序始终可以再次将用户发送回流程,以获取其他权限,但是请不要忘记用户总是可以拒绝。
client_id就是注册给的那个,redirect_uri就是你写的回调地址,通过访问这个地址获取令牌
Name | Type | Description |
---|---|---|
client_id |
string |
Required. The client ID you received from GitHub when you registered 必需的。注册时从GitHub收到的客户端ID。 |
redirect_uri |
string |
The URL in your application where users will be sent after authorization. See details below about redirect urls应用程序中的URL,用户将在授权后发送到该URL。请参阅下面关于重定向url的详细信息。 |
login |
string |
Suggests a specific account to use for signing in and authorizing the app.建议使用一个特定的帐户来登录和授权应用程序。 |
scope |
`string | 以空格分隔的范围列表。如果没有提供作用域,对于没有为应用程序授权任何作用域的用户,作用域默认为空列表。对于已经为应用程序授权了范围的用户,不会显示带有范围列表的OAuth授权页面。相反,流的这一步将使用用户为应用程序授权的范围集自动完成。例如,如果用户已经执行了两次web流,并且授权了一个具有用户范围的令牌和另一个具有回购范围的令牌,则第三个web流不提供sc |
state |
string |
An unguessable random string. It is used to protect against cross-site request forgery attacks.不可猜测的随机字符串。它用于防止跨站点请求伪造攻击。 |
allow_signup |
string |
Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. The default is true . Use false in the case that a policy prohibits signups.在OAuth流期间,是否会为未经身份验证的用户提供一个注册GitHub的选项。默认值为true。在策略禁止注册的情况下使用false。 |
通过获取的code和state,利用httpclient来获取AccessToken
java代码callback接口如下:
@Value("${github.client.id}") private String id; @Value("${github.client.secret}") private String secret; @Value("${github.redirect.uri}") private String uri; @RequestMapping("/callback") public String callback(@RequestParam(name = "code") String code, @RequestParam(name = "state") String state, HttpServletResponse response) { //通过一个DTO对象封装,接收的code state AccessTokenDTO accessTokenDTO = new AccessTokenDTO(); accessTokenDTO.setCode(code); accessTokenDTO.setClient_id(id); accessTokenDTO.setClient_secret(secret); accessTokenDTO.setState(state); accessTokenDTO.setRedirect_uri(uri); //得到github传回来的数据 code + Client Secret+Client id来获取token String accessToken = githubProvider.getAccessToken(accessTokenDTO); //通过解析封装成一个对象 GithubUser githubUser = githubProvider.getUser(accessToken); if (githubUser != null) { //写入数据库 } //login success // request.getSession().setAttribute("user",githubUser); return "redirect:/"; } else { return "redirect:/"; }
利用获取过来的AccessToken来再次访问github来获取用户信息
其中githubprovider代码如下:
public String getAccessToken(AccessTokenDTO accessTokenDTO) { //