Oauth2.0 认证协议

Oauth2.0 应用场景: 微信联合登录     授权管理

互联网开放平台互相调用保证安全

微信提供api  给toov5调用  然后就可以获取一些微信的信息  比如微信头像

开放平台有 支付宝  微信 百度等等

不同的开放平台 对接的oauth2.0协议流程都是相同,无非接口地址不同

Oauth2.0原理 (appId appsecret access_token  openId  回调地址 授权地址)

使用:

在微信开放平台申请对应的appId信息

toov5生成登录授权连接

用于在确认微信登录之后  跳转回到回调地址(配置域名权限)

获取到授权码 使用授权码获取对应的accessToken(调用腾讯借口权限)

使用accessToken+openId获取用户相关信息 (openid 开放userId)

配置 授权访问连接: 通过controller跳转到 腾讯的连接

用户点击确定登录时候  进入到callback,并且获取到前面返回的code

拿到code 后面就可以获取到相应的 token 和 id了

第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
5 附:检验授权凭证(access_token)是否有效

maven:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies> <!-- SpringBoot 对lombok 支持 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <!-- SpringBoot web 核心组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- SpringBoot 外部tomcat支持 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency> <!-- springboot-log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- springboot-aop 技术 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency> <dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>

yml:

spring:
mvc:
view:
# 页面默认前缀目录
prefix: /WEB-INF/jsp/
# 响应页面默认后缀
suffix: .jsp appid: wx5c43fde3c9733d9e
secret: b8b217126c33a5fb7074927d5e72a81a
redirectUri: http://127.0.0.1:8080/callback
### 生成微信授权 官方提供的授权接口
authorizedUrl: https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
###获取code后,请求以下链接获取access_token
access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
###拉取用户信息(需scope为 snsapi_userinfo)
userinfo: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

Controller:

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSONObject;
import com.itmayiedu.base.BaseApiService;
import com.itmayiedu.utils.HttpClientUtils;
import com.itmayiedu.utils.WeiXinUtils; @Controller
public class OauthController extends BaseApiService { @Autowired
private WeiXinUtils weiXinUtils;
private String errorPage = "errorPage"; // 生成授权链接
@RequestMapping("/authorizedUrl")
public String authorizedUrl() {
System.out.println(weiXinUtils.getAuthorizedUrl());
return "redirect:" + weiXinUtils.getAuthorizedUrl(); //重定向到微信的开放平台地址
} // 微信授权回调地址
@RequestMapping("/callback")
public String callback(String code, HttpServletRequest request) {
// 1.使用Code 获取 access_token
String accessTokenUrl = weiXinUtils.getAccessTokenUrl(code);
JSONObject resultAccessToken = HttpClientUtils.httpGet(accessTokenUrl);
boolean containsKey = resultAccessToken.containsKey("errcode"); if (containsKey) {
request.setAttribute("errorMsg", "系统错误!");
return errorPage;
}
// 2.使用access_token获取用户信息
String accessToken = resultAccessToken.getString("access_token");
String openid = resultAccessToken.getString("openid");
// 3.拉取用户信息(需scope为 snsapi_userinfo)
String userInfoUrl = weiXinUtils.getUserInfo(accessToken, openid);
JSONObject userInfoResult = HttpClientUtils.httpGet(userInfoUrl);
System.out.println("userInfoResult:" + userInfoResult);
request.setAttribute("nickname", userInfoResult.getString("nickname"));
request.setAttribute("city", userInfoResult.getString("city"));
request.setAttribute("headimgurl", userInfoResult.getString("headimgurl"));
return "info";
} }

Base:

import org.springframework.stereotype.Component;

import com.itmayiedu.utils.Constants;

@Component
public class BaseApiService { public ResponseBase setResultError(Integer code, String msg) {
return setResult(code, msg, null);
} // 返回错误,可以传msg
public ResponseBase setResultError(String msg) {
return setResult(Constants.HTTP_RES_CODE_500, msg, null);
} // 返回成功,可以传data值
public ResponseBase setResultSuccessData(Object data) {
return setResult(Constants.HTTP_RES_CODE_200, Constants.HTTP_RES_CODE_200_VALUE, data);
} public ResponseBase setResultSuccessData(Integer code, Object data) {
return setResult(code, Constants.HTTP_RES_CODE_200_VALUE, data);
} // 返回成功,沒有data值
public ResponseBase setResultSuccess() {
return setResult(Constants.HTTP_RES_CODE_200, Constants.HTTP_RES_CODE_200_VALUE, null);
} // 返回成功,沒有data值
public ResponseBase setResultSuccess(String msg) {
return setResult(Constants.HTTP_RES_CODE_200, msg, null);
} // 通用封装
public ResponseBase setResult(Integer code, String msg, Object data) {
return new ResponseBase(code, msg, data);
} }
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; @Getter
@Setter
@Slf4j
public class ResponseBase { private Integer rtnCode;
private String msg;
private Object data; public ResponseBase() { } public ResponseBase(Integer rtnCode, String msg, Object data) {
super();
this.rtnCode = rtnCode;
this.msg = msg;
this.data = data;
} public static void main(String[] args) {
ResponseBase responseBase = new ResponseBase();
responseBase.setData("123456");
responseBase.setMsg("success");
responseBase.setRtnCode(200);
System.out.println(responseBase.toString());
log.info("itmayiedu...");
} @Override
public String toString() {
return "ResponseBase [rtnCode=" + rtnCode + ", msg=" + msg + ", data=" + data + "]";
} }

Entity:

public class AppEntity {

    private long id;
private String appId;
private String appName;
private String appSecret;
private String accessToken;
private String redirectUri;
private int isFlag; public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getAppId() {
return appId;
} public void setAppId(String appId) {
this.appId = appId;
} public String getAppName() {
return appName;
} public void setAppName(String appName) {
this.appName = appName;
} public String getAppSecret() {
return appSecret;
} public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
} public int getIsFlag() {
return isFlag;
} public void setIsFlag(int isFlag) {
this.isFlag = isFlag;
} public String getAccessToken() {
return accessToken;
} public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
} public String getRedirectUri() {
return redirectUri;
} public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
} }
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; @Getter
@Setter
@Slf4j
public class ResponseBase { private Integer rtnCode;
private String msg;
private Object data; public ResponseBase() { } public ResponseBase(Integer rtnCode, String msg, Object data) {
super();
this.rtnCode = rtnCode;
this.msg = msg;
this.data = data;
} public static void main(String[] args) {
ResponseBase responseBase = new ResponseBase();
responseBase.setData("123456");
responseBase.setMsg("success");
responseBase.setRtnCode(200);
System.out.println(responseBase.toString());
log.info("itmayiedu...");
} @Override
public String toString() {
return "ResponseBase [rtnCode=" + rtnCode + ", msg=" + msg + ", data=" + data + "]";
} }

Util:

public interface Constants {
// 响应请求成功
String HTTP_RES_CODE_200_VALUE = "success";
// 系统错误
String HTTP_RES_CODE_500_VALUE = "fial";
// 响应请求成功code
Integer HTTP_RES_CODE_200 = 200;
// 系统错误
Integer HTTP_RES_CODE_500 = 500;
// 未关联QQ账号
Integer HTTP_RES_CODE_201 = 201;
// 发送邮件
String MSG_EMAIL = "email";
// 会员token
String TOKEN_MEMBER = "TOKEN_MEMBER";
// 支付token
String TOKEN_PAY = "TOKEN_pay";
// 支付成功
String PAY_SUCCESS = "success";
// 支付白
String PAY_FAIL = "fail";
// 用户有效期 90天
Long TOKEN_MEMBER_TIME = (long) (60 * 60 * 24 * 90);
int COOKIE_TOKEN_MEMBER_TIME = (60 * 60 * 24 * 90);
Long PAY_TOKEN_MEMBER_TIME = (long) (60 * 15);
// cookie 会员 totoken 名称
String COOKIE_MEMBER_TOKEN = "cookie_member_token"; }
import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSONObject; public class HttpClientUtils {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录 private static RequestConfig requestConfig = null; static {
// 设置请求和传输超时时间
requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
} public static JSONObject httpPost(String url, JSONObject jsonParam) {
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
// 设置请求和传输超时时间
httpPost.setConfig(requestConfig);
try {
if (null != jsonParam) {
// 解决中文乱码问题
StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post请求提交失败:" + url, e);
}
}
} catch (IOException e) {
logger.error("post请求提交失败:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
} public static JSONObject httpPost(String url, String strParam) {
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
try {
if (null != strParam) {
// 解决中文乱码问题
StringEntity entity = new StringEntity(strParam, "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post请求提交失败:" + url, e);
}
}
} catch (IOException e) {
logger.error("post请求提交失败:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
} public static JSONObject httpGet(String url) {
// get请求返回结果
JSONObject jsonResult = null;
CloseableHttpClient client = HttpClients.createDefault();
// 发送get请求
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
try {
CloseableHttpResponse response = client.execute(request); // 请求发送成功,并得到响应
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 读取服务器返回过来的json字符串数据
HttpEntity entity = response.getEntity();
String strResult = EntityUtils.toString(entity, "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(strResult);
} else {
logger.error("get请求提交失败:" + url);
}
} catch (IOException e) {
logger.error("get请求提交失败:" + url, e);
} finally {
request.releaseConnection();
}
return jsonResult;
} }
import java.net.URLEncoder;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping; @Component
public class WeiXinUtils {
@Value("${appid}")
private String appId;
@Value("${secret}")
private String secret;
@Value("${redirecturi}")
private String redirectUri;
@Value("${authorizedUrl}")
private String authorizedUrl;
@Value("${access_token}")
private String accessToken;
@Value("${userinfo}")
private String userinfo; public String getAuthorizedUrl() {
return authorizedUrl.replace("APPID", appId).replace("REDIRECT_URI", URLEncoder.encode(redirectUri));
} public String getAccessTokenUrl(String code) {
return accessToken.replace("APPID", appId).replace("SECRET", secret).replace("CODE", code);
} public String getUserInfo(String accessToken, String openId) {
return userinfo.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
} }

启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class AppOauth { public static void main(String[] args) {
SpringApplication.run(AppOauth.class, args);
} }

Oauth2.0认证原理的更多相关文章

  1. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  2. C# 网络编程之豆瓣OAuth2.0认证具体解释和遇到的各种问题及解决

            近期在帮人弄一个豆瓣API应用,在豆瓣的OAuth2.0认证过程中遇到了各种问题,同一时候自己须要一个个的尝试与解决,终于完毕了豆瓣API的訪问.作者这里就不再吐槽豆瓣的认证文档了,毕 ...

  3. .Net WebApi 实现OAuth2.0认证

    现在多数公众平台提供的api都使用OAuth2.0认证模式,最近在搞Android方面的开发,身份认证和权限控制的各方面比较来说,使用OAuth认证的还是比较靠谱,OAuth2.0的协议可以参考htt ...

  4. Owin中间件搭建OAuth2.0认证授权服务体会

    继两篇转载的Owin搭建OAuth 2.0的文章,使用Owin中间件搭建OAuth2.0认证授权服务器和理解OAuth 2.0之后,我想把最近整理的资料做一下总结. 前两篇主要是介绍概念和一个基本的D ...

  5. OAuth2.0认证介绍

    OAuth2.0鉴权 返回 目录 [隐藏] 1 腾讯微博OAuth2.0认证介绍 2 获取accesstoken的两种方式 2.1 1.Authorization code grant 2.1.1 第 ...

  6. OAuth2.0认证详解

    目录 什么是OAuth协议 OAuth2.0是为了解决什么问题? OAuth2.0成员和授权基本流程 OAuth2.0成员 OAuth2.0基本流程 什么是OAuth协议 OAuth 协议为用户资源的 ...

  7. Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务

    API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...

  8. Oauth2.0 认证的Web api例子

    Oauth2.0的解释 OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容.OA ...

  9. QQ登录整合/oauth2.0认证-04-调整到QQ互联进行QQ登录

    ---------------------------------目录------------------------------------- QQ登录整合/oauth2.0认证-03-对第二节的代 ...

随机推荐

  1. 如何下载ubuntu桌面,并使用

    下载ubuntu,进行linux系统的操作 1.下载ubuntu 百度搜索ubuntu或直达下载链接http://cn.ubuntu.com/download/ 你可以选择,优麒麟16或者Ubuntu ...

  2. Android中流式布局和热门标签

    1.流式布局特点.应用场景.2.自定义ViewGroup (1)onMeasure:测量子View的宽和高,设置自己的宽和高. (2)onLayout:设置子View的位置. onMeasure:根据 ...

  3. pycharm 变量批量重命名

    Ctrl + R 替换 Ctrl + Shift + F 全局查找 Ctrl + Shift + R 全局替换

  4. UI层复习笔记

    在main文件中,UIApplicationMain函数一共做了三件事 根据第三个参数创建了一个应用程序对象 默认写nil,即创建的是UIApplication类型的对象,此对象看成是整个应用程序的一 ...

  5. 【BZOJ1922】[Sdoi2010]大陆争霸 Dijkstra

    Description 具体地说,杰森国有 N 个城市,由 M条单向道 路连接.神谕镇是城市 1而杰森国的首都是城市 N.你只需摧毁位于杰森国首都 的曾·布拉泽大神殿,杰森国的信仰,军队还有一切就都会 ...

  6. 【文章阅读】Java虚拟机系列学习

    总目录: Java虚拟机 - 随笔分类 - 五月的仓颉 - 博客园 http://www.cnblogs.com/xrq730/category/731395.html 已读: Java虚拟机1:什么 ...

  7. HDU 1233 还是畅通工程(Kruskal)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  8. AI篇6====>第一讲

    1.人工智能 小米:小爱 百度:AI云平台 科大讯飞AI平台 2.百度语音合成 # Author: studybrother sun from aip import AipSpeech #从文本到声音 ...

  9. MySQL 乐观锁与悲观锁

    悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁. 悲观锁: ...

  10. 解决ubuntu 无法挂载移动硬盘问题 unknown filesystem type 'exfat'

    Ubuntu 13.10 或以上 安装exfat-fuse: sudo apt-get install exfat-fuse Ubuntu 13.04 或以下 sudo apt-add-reposit ...