github认证登陆

使用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) {
       //设置从GitHub那里获取的数据设置成josn格式
         MediaType mediaType = MediaType.get("application/json; charset=utf-8");
         OkHttpClient client = new OkHttpClient();
         //通过okhttclient来获取github传过来的用户信息,要利用到AceessTokenDTO内的数据!
          //将传过来的accesstokendto转化为json格式,通过post形式传给github
         RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(accessTokenDTO));
         Request request = new Request.Builder()
                 .url("https://github.com/login/oauth/access_token")
                 .post(body)
                 .build();
         try (Response response = client.newCall(request).execute()) {
             String string = response.body().string();
             //把传过来的token解析
             String token = string.split("&")[0].split("=")[1];
             return token;
         } catch (Exception e) {
             //log.error("getAccessToken error,{}", accessTokenDTO, e);
         }
         return null;
     }
 ?
     public GithubUser getUser(String accessToken) {
         //通过得到的token获取user
         OkHttpClient client = new OkHttpClient();
         Request request = new Request.Builder()
                 .url("https://api.github.com/user?access_token=" + accessToken)
                 .build();
         try {
             Response response = client.newCall(request).execute();
             String string = response.body().string();
             //封装
             GithubUser githubUser = JSON.parseObject(string, GithubUser.class);
             //System.out.println(string);
             return githubUser;
         } catch (Exception e) {
            // log.error("getUser error,{}", accessToken, e);
         }
         return null;
     }

获取的json内容如下:

 //封装
 JSON.parseObject(string, GithubUser.class);

 {
     "login": "Diamondtest",
     "id": 28478049,
     "avatar_url": "https://avatars0.githubusercontent.com/u/28478049?v=3",
     "gravatar_id": "",
     "url": "https://api.github.com/users/Diamondtest",
     "html_url": "https://github.com/Diamondtest",
     "followers_url": "https://api.github.com/users/Diamondtest/followers",
     "following_url": "https://api.github.com/users/Diamondtest/following{/other_user}",
     "gists_url": "https://api.github.com/users/Diamondtest/gists{/gist_id}",
     "starred_url": "https://api.github.com/users/Diamondtest/starred{/owner}{/repo}",
     "subscriptions_url": "https://api.github.com/users/Diamondtest/subscriptions",
     "organizations_url": "https://api.github.com/users/Diamondtest/orgs",
     "repos_url": "https://api.github.com/users/Diamondtest/repos",
     "events_url": "https://api.github.com/users/Diamondtest/events{/privacy}",
     "received_events_url": "https://api.github.com/users/Diamondtest/received_events",
     "type": "User",
     "site_admin": false,
     "name": null,
     "company": null,
     "blog": "",
     "location": null,
     "email": null,
     "hireable": null,
     "bio": null,
     "public_repos": 0,
     "public_gists": 0,
     "followers": 0,
     "following": 0,
     "created_at": "2017-05-06T08:08:09Z",
     "updated_at": "2017-05-06T08:16:22Z"
 }

授权之后,每次登陆都不需要再次授权,可更换浏览器或者选择revoke all user tokens 就可以了!

okhttpclient的用例与介绍

介绍

OkHttp是一个HTTP客户机,默认情况下是高效的:

  • http/2支持允许对同一主机的所有请求共享套接字。
  • 连接池可以减少请求延迟(如果HTTP/2不可用)。
  • 透明GZIP缩小下载大小。
  • 响应缓存完全避免了重复请求的网络。
 OkHttpClient client = new OkHttpClient();
 //获取URL
 //访问URL并获取该网站返回过来的字符串
 String run(String url) throws IOException {
   Request request = new Request.Builder()
       .url(url)
       .build();
 ?
   try (Response response = client.newCall(request).execute()) {
     return response.body().string();
   }
 }

 public static final MediaType JSON
     = MediaType.get("application/json; charset=utf-8");
 ?
 OkHttpClient client = new OkHttpClient();
 //发送到服务器
 //通过build一个request 并将需要的参数封装到body 访问url,执行client.newCall(request).execute(),得到返回值,一般是一个json格式的字符串,当然也可以自己选择它的返回数据格式!
 String post(String url, String json) throws IOException {
   RequestBody body = RequestBody.create(json, JSON);
   Request request = new Request.Builder()
       .url(url)
       .post(body)
       .build();
   try (Response response = client.newCall(request).execute()) {
     return response.body().string();
   }
 }

详情参见:okhttp

githubdeveloper手册

原文地址:https://www.cnblogs.com/awsljava/p/11596077.html

时间: 2024-10-31 18:47:40

github认证登陆的相关文章

mongodb3.2集群认证登陆

继mongodb3.2复制集和shard集群之后的用户认证登陆. 1:关于mongos登录权限认证配置 [[email protected] keyfile]$ openssl rand -base64 741 > /data/keyfile/zxl [[email protected] keyfile]$ chmod 600 /data/keyfile/zxl 2:把/data/keyfile/zxl文件拷贝到各个机器/data/keyfile/目录下即可 切记属主和组以及文件权限600 3:

SharePoint2013基于Form(FBA)的AD认证登陆

来源于:http://www.haogongju.net/art/1964313 1. 使用SharePoint2013实现基于AD的Form认证,首先创建一个Web Application,步骤如下:Central Administration -> Application Management -> Manage Web Application -> New Web Application; 填写web application 端口,允许或者不允许Anonymous等等: 虽然我们只

Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)

优秀的平台必然松耦合.易扩展  -- 王昕 第一步:修改liferay-hook.xml <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd"> <hook> <portal-properties>

Ngnix服务器下面的强身份认证登陆的实现

Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,,因它的稳定性.丰富的功能集.示例配置文件和低系统资源的消耗而闻名.今天小编给大家讲讲如何实现客户端强身份认证登陆:1.首先需要配置站点的SSl证书 打开Nginx安装目录下conf目录中的nginx.conf文件 找到    # HTTPS serv

ssh基于key认证登陆

ssh基于key认证登陆一.在客户端生成密钥对 ssh-keygen -t rsa [-P ''] [-f "~/.ssh/id_rsa"] ## -r rsa:指定算法 ## -P :加对称秘钥口令 ## -f :可以指定生成路径 ## /.ssh/id_rsa 生成秘钥默认路径 我们简单操作就不加密码了 [[email protected] .ssh]# ssh-keygen Generating public/private rsa key pair. Enter file in

配置key认证登陆Ubuntu (下)

梗概: 使用证书登陆,可以减少密码的使用,避免密码泄露,证书登陆更加方便.安全. Secure CRT 和Putty 原理相同,生成 密钥对(Key pair)操作有所不同. 1.生成key pair, 先以SecureCRT 为例 密钥类型有RSA 和 DSA两种,sshd_config里面两种都支持,一般选用RSA. 长度512-2048位任选. 通行短语:这个地方类似是一条口令,在建立Session的时候会要求输入,个人觉得没必要填写,填了相当于在证书登陆的过程中又加入了密码这种东西. 注

ssh &nbsp; sshd &nbsp; scp &nbsp; 基于密钥认证登陆 双机互信

telnet :远程登陆 TCP/23 远程认证是明文的 :数据传输是明文的:不实用 ssh:Secure SHell TCP/22    协议 v1 v2  v1基本不使用的 实现了将认证过程加密 Openssh:是ssh的开源版 ssh不仅是一个软件,也是一种协议 ssh加密认证的机制 基于口令:默认为口令 基于密钥:事先在服务器端的用户里放入客户端的公钥,然后链接过来的时候对暗号 netstat -tnl  查看服务器端打开了等待别人访问的服务 LISTEN监听 ssh 和sshd的配置文

django中的认证登陆与用户的创建

---恢复内容开始--- from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1  authenticate()   提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数 如果认证信息有效,会返回一个  User  对象.authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的.当我们

Apache2.4 用户认证登陆笔记!

apache用户认证用利于进一步安全你的apache站点,简单做个笔记. 1.创建指定用户,并指明密码. [[email protected] apache2]# htpasswd -c /usr/local/apache2/passwords renzhiyuan New password:  Re-type new password:  Adding password for user renzhiyuan [[email protected] apache2]# 2.编辑http.conf