了解oauth2.0

这篇具有很好参考价值的文章主要介绍了了解oauth2.0。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 什么是 OAuth2.0

开发授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片、视频、联系人列表等),而无需将用户名和密码提供给第三方应用。

OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下里的2小时内)访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站他们存储在另外服务提供者的某些特定信息,而非所有内容。

OAuth 是 OpenID 的一个补充,但是完全不同的服务。

OAuth 2.0

OAuth 2.0 是 OAuth 协议的下一版本,但不向下兼容 OAuth 1.0。OAuth 2.0 关注客户端开发者的简易性,同时为Web应用、桌面应用、手机和智慧设备提供专门的认证流程。

2 应用场景

参考自阮一峰的理解OAuth的适用场景的例子。

有一个“云冲印”的网站,支持将用户存在各大服务商(包括但不限于百度网盘,Google网盘等)存储的图片打印出来,现在用户想利用“云冲印”来打印他存储在百度网盘的图片。那么问题来了:“云冲印”如何拿到用户存储在百度网盘的图片呢?

答:“云冲印”需要得到用户的授权(即授权“云冲印”读取存储在百度网盘的图片)。传统的方法可能是,用户将自己百度网盘的用户名和密码告诉“云冲印”,后者就可以读取用户的照片了。但这样的做法有以下几个严重的缺点:

  1. “云冲印”为了后续的服务,“云冲印”需要保存该用户的百度网盘的用户名和密码,这会对“云冲印”公司带来额外的存储开销。
  2. “云冲印”拥有了用户存储在百度网盘所有自资料的权利,用户没法限制“云冲印”获得授权的范围和有效期。
  3. 用户修改了百度网盘的密码后,“云冲印”必须也要同步修改密码才能正常使用服务,这很显然是不合理的。

OAuth就是为了解决上述问题而诞生的。

3 名词定义

在深入了解OAuth 2.0之前,需要了解几个专用名词。

  • Third-party application:第三方应用程序,即上一节例子中的“云冲印”。
  • HTTP service:HTTP 服务提供商,即上一节例子中的“百度网盘”。
  • Resource Owner:资源所有者,又称“用户”。
  • User Agent:用户代理,一般是浏览器。
  • Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器可以同在一台服务器也可以不同在一台服务器。

了解了上述名词,就不难理解,OAuth的作用就是让“客户端”安全可控地获取“用户”的授权,与“服务提供商”进行互动。

4 OAuth 思路

OAuth 使得“第三方应用程序”与“服务提供商”之间多了一个授权层(authorization layer)。“第三方应用程序”不能直接登录“服务提供商”,只能访问授权层,以此将用户与“第三方应用程序”区分来。“第三方应用程序”登录授权层所用的令牌,与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

“第三方应用程序”登录授权层后,“服务提供商”根据令牌的权限范围和有效期,向“第三方应用程序”开放用户存储的资料。

5 运行流程

OAuth 2.0 的运行流程如下图

了解oauth2.0

A) 用户打开第三方程序后,第三方程序要求用户给予授权。

B) 用户同意给予第三方程序授权。

C) 第三方程序使用上一步获得的授权,向认证服务器申请令牌。

D) 认证服务器对第三方程序进行认证后,确认无误,同意发放令牌。

E) 第三方程序使用令牌,向资源服务器申请获取资源。

F) 资源服务器确认令牌无误,同意向客户端开放资源。

6 第三方程序的授权模式

第三方程序必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0 定义了四种授权方式:

  • 授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与“服务提供商”的认证服务器进行互动。
  • 简化模式(implicit)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了“授权码”这个步骤。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
  • 密码模式(resource owner password credentials)用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
  • 客户端模式(client credentials)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。

7 OAuth 接入第三方程序示例

基本上遵循 OAuth 协议的第三方程序都是以下流程,举例 A 网站允许 Github 登录,差不多就是以下流程:

  1. A 网站引导用户跳转到 Github。
  2. Github 要求用户登录,并询问“ A 网站要求获得 XX 权限,是否同意?”
  3. 用户登录并同意后 Github 就会重定向回 A 网站,同时发回一个授权码。
  4. A 网站使用授权码,向 Github 请求令牌。
  5. Github 返回令牌。
  6. A 网站使用令牌,访问用户存储在 Github 的数据。

以下以gitee为例,集成OAuth:

a) 应用登记

访问这个网址完成App登记:https://gitee.com/oauth/applications/new

应用名称随便填,主页URL填http://localhost:8090,应用回调地址填http://localhost:8090/gitee/oauth/callback,再随便上传一个图片作为Logo。填写完成后 gitee 会返回供 gitee 识别的该第三方应用的 ClientID 和 ClientSecret 身份识别码。

了解oauth2.0

b) 第三方应用程序请求授权码

运行示例代码,然后浏览器输入

http://localhost:8090/gitee/authorize

此时浏览器会重定向到(如果此时你没有登录gitee,则会要求先登录gitee)

https://gitee.com/oauth/authorize?client_id=894c85cea5b36cd629a3cf0867778692acbad55877487e111f4683312bc512cb&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2Fgitee%2Foauth%2Fcallback&response_type=code

该 url 中包含了client_id:在gitee申请的第三方程序的识别的ID,和redirect_uri:同意授权后gitee会回调的地址(会携带一个授权码code)以及response_type指定授权模式,这里是授权码模式即code。

此时你确认是否同意授权以及第三方程序访问的范围

了解oauth2.0

点击同意后,浏览器则会回调刚填入的redirect_uri,这里则是

http://localhost:8090/gitee/oauth/callback?code=18ca69350dfb2f139829944845a017cef6bfddec01c2d71e507cbdbf51962b1c

会看到这里会携带一个授权码code,接着就需要利用这个code向gitee申请令牌。

C) 获得token

可以看到已经拿到token了。这是因为后端在拿到code后直接向gitee发起申请得到token了并且返回。

了解oauth2.0

此时已经完成了用授权码code申请到了token,接下来就可以使用token获取用户存储在gitee的资源了。

D) 获取资源

拿到token后具体可以使用哪些API可以参阅文档,文档中有API的method以及可选参数:https://gitee.com/api/v5/swagger,这里演示:获取授权用户的资料(即当前用户的资料):https://gitee.com/api/v5/user 浏览器输入

https://gitee.com/api/v5/user?access_token=5d3b7a6d1602934d12709xxxxx

即可以获取到用户的资料了

了解oauth2.0

恭喜你,你已经可以在第三方程序发起请求使用gitee登录了(表面上的)

接下来将带你了解后端代码具体如何与gitee交互的。

E) 后端实现

这里以gitee的实现为例,github或者gitlab可以自行参考代码。

1 第三方App向服务提供商发起获得授权的申请
// curl -X GET http://localhost:8090/gitee/authorize

// Authorize
// 向服务提供商gitee发起获得授权码的申请
func Authorize(c *gin.Context) {
	u, _ := url.Parse("https://gitee.com/oauth/authorize")
	values := u.Query()
	values.Set("client_id", ClientId)
	values.Set("redirect_uri", "http://localhost:8090/gitee/oauth/callback")
	values.Set("response_type", "code")
	u.RawQuery = values.Encode()

	// redirect to -> https://gitee.com/oauth/authorize?client_id={CLIENT_ID}&redirect_uri=http://localhost:8090/gitee/oauth/callback&response_type=code
	c.Redirect(http.StatusMovedPermanently, u.String())
	return
}

使用GET请求该App的/gitee/authorize资源,服务端就会将clientIdredirect_uriresponse_type拼凑到向gitee发起请求的url上,并重定向到该url。此时浏览器会转到服务提供商(这里是gitee),gitee就会向登录的用户发起提示:是否允许该第三方App访问你的gitee资源,并且还会提示资源访问的范围。

2 第三方App获取到授权码code,并使用code获取token
// Callback
// 用户同意授权后
func Callback(c *gin.Context) {
	code := c.Query("code")
	u, _ := url.Parse("https://gitee.com/oauth/token")
	values := u.Query()
	values.Set("client_id", ClientId)
	values.Set("client_secret", ClientSecret)
	values.Set("code", code)
	values.Set("grant_type", "authorization_code")
	values.Set("redirect_uri", "http://localhost:8090/gitee/oauth/callback")
	u.RawQuery = values.Encode()

	client := http.DefaultClient
	req, _ := http.NewRequest(http.MethodPost, u.String(), nil)
	req.Header.Set("accept", "application/json")
	res, _ := client.Do(req)
	// HTTP POST -> https://gitee.com/oauth/token?client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code={CODE}&grant_type=authorization_code&redirect_uri=http://localhost:8090/gitee/oauth/callback
	defer res.Body.Close()
	bytes, _ := ioutil.ReadAll(res.Body)
	fmt.Println(string(bytes))

	obj := make(map[string]interface{})
	json.Unmarshal(bytes, &obj)
	c.JSON(http.StatusOK, obj)
	return
}

待上述第1步完成后,gitee会携带授权码code回调服务端redirect_uri的地址/gitee/oauth/callback。此时服务端会将client_idclient_secretcodegrant_typeredirect_uri拼凑到向gitee发起请求的url上,指定接受json格式的返回值,此时返回的json就是一个包含token的对象了。

3 使用token获取gitee资源
func Userinfo(c *gin.Context) {
	token := c.Query("token")

	u, _ := url.Parse("https://gitee.com/api/v5/user")
	values := u.Query()
	values.Set("access_token", token)
	u.RawQuery = values.Encode()

	client := http.DefaultClient
	req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
	req.Header.Set("accept", "application/json")
	res, _ := client.Do(req)
	// HTTP GET -> https://gitee.com/api/v5/user?access_token={TOKEN}
	defer res.Body.Close()
	bytes, _ := ioutil.ReadAll(res.Body)
	fmt.Println(string(bytes))

	info := new(UserInfo)
	json.Unmarshal(bytes, &info)
	c.JSON(http.StatusOK, info)
	return
}

待第2步获取到token后,我们就可以使用该token访问用户存储在gitee的资源了。使用GET请求将token作为query访问/gitee/userinfo,此时服务端就会将此token拼凑到向gitee请求资源的url上,发起GET请求,制定接受json格式的返回值,此时gitee就会返回该token对应的userinfo了。

思考

通过Oauth2.0的方式第三方应用申请到的token一般包含access_tokenrefresh_token,第三方应用分别利用access_tokenrefresh_token向资源提供商获取资源和刷新token,第三方应用能够从资源提供商获取资源但是没有办法在自己内部存储该资源所有者的信息,因为第三方应用无法将token和资源所有者进行关联(因为token会不断重置,第三方应用无法将此作为唯一标识来确认资源所有者)。以网易云音乐为例,允许资源所有者以QQor微信or微博等第三方登陆,网易云音乐使用第三方登录成功后,会在网易云音乐这里存储下资源所有者的头像、资源所有者名等等,并且下次使用第三方登录的时候仍然会指向该资源所有者,这就是利用了Oauth2.0更上层的实现OIDC来实现的,因为OIDC不仅会返回access_tokenrefresh_token还会返回id_token(即资源所有者的token),这样第三方应用就能够将资源所有者进行存储了。

示例仓库

示例仓库

https://github.com/FanGaoXS/oauth_demo.git

代码用Go集成了giteegithubgitlab的OAuth实现,记得阅读README然后根据实际情况修改.env文件中的配置信息。

参考自

理解OAuth 2.0:https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html文章来源地址https://www.toymoban.com/news/detail-493629.html

到了这里,关于了解oauth2.0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot整合springsecurity+oauth2.0密码授权模式

    本文采用的springboot去整合springsecurity,采用oauth2.0授权认证,使用jwt对token增强。本文仅为学习记录,如有不足多谢提出。 OAuth 2.0是用于授权的行业标准协议。OAuth 2.0为简化客户端开发提供了特定的授权流,包括Web应用、桌面应用、移动端应用等。 Resource owner(资源拥有者)

    2024年02月04日
    浏览(57)
  • 五、SpringSecurity OAuth2扩展手机验证码授权模式

    代码仓库:地址 代码分支:lesson5 在上一篇文章中,我们使用SpringSecurity OAuth2搭建了一套授权服务,对业务系统进行统一授权管理。OAuth提供了四种授权方式: 授权码模式(authorization_code) 简化模式(implicit) 客户端(client_credentials) 密码(password) 在实际业务中上述四种模式不

    2024年02月11日
    浏览(54)
  • 【Oauth2.0 单点登录 + 第三方授权认证】用户认证、授权模式

    本文主要对 SpringSecurity Oauth 2.0 用户认证,授权码授权模式、密码授权模式,以及授权流程进行讲解 开发中,有些功能只有管理员才有,普通用户是没有的。即需要对用户的身份进行认证,是管理员还是普通用户。认证方式有两种: 身份认证: 用户在访问相应资源时对用户

    2023年04月08日
    浏览(62)
  • Spring Security—OAuth2 客户端认证和授权

    关于 JWT Bearer 客户端认证的进一步详情,请参考OAuth 2.0客户端认证和授权许可的 JSON Web Token (JWT)简介。 JWT Bearer 客户端认证的默认实现是  NimbusJwtClientAuthenticationParametersConverter ,它是一个  Converter ,通过在  client_assertion  参数中添加签名的JSON Web Token(JWS)来定制令牌请求

    2024年02月08日
    浏览(51)
  • oauth2-resource-server授权配置介绍

    当了解这篇文章授权服务器后,对授权服务器有一定的认识,那么授权服务器生成token后,该怎么用呢,这就涉及到资源服务器,现在给大家简单介绍实现过程。 2.1 基于官网配置 首先先配置 issuer-uri ,这里指向是授权服务器的地址 关于过滤器链的配置: 资源服务器将使用

    2024年02月12日
    浏览(30)
  • 搭建spring security oauth2认证授权服务器

    下面是在spring security项目的基础上搭建spring security oauth2认证授权服务器 spring security oauth2认证授权服务器主要需要以下依赖 Spring Security对OAuth2默认可访问端点 ​/oauth/authorize​ ​​:申请授权码code,涉及类​ ​AuthorizationEndpoint​ ​ ​/oauth/token​ ​​:获取令牌token,涉及类​

    2024年01月21日
    浏览(55)
  • B094-人力资源项目-微服务授权&Oauth2

    背景 微服务架构下应用散步在不同的服务器上,不是一个tomcat ,不能再基于Session 不同的服务不同的功能,都要有权限控制,不能再基于Session用Security 微服务权限控制用Redis: 微服务用Redis做权限控制数据不好存 要查Redis, 权限变动时数据库与redis需要同步,redis不好改,如

    2024年02月09日
    浏览(32)
  • 自定义OAuth2组件实现对授权码登录模式的封装

    所谓OAuth2其实就是Open Authorization,即开放授权,是一种授权机制或者说是一种协议。 OAuth2允许用户授权第三方应用访问其存储在开放平台(授权服务器)中的数据而不需要提供密码 。授权服务器根据OAuth2协议标准制订一套授权的API,第三方网站接入开放平台之后即可通过其

    2024年02月05日
    浏览(37)
  • SpringSecurity:OAuth2 Client 结合GitHub授权案例(特简单版)

    本随笔说明:这仅作为OAuth2 Client初次使用的案例,所以写得很简单,有许多的不足之处。 OAuth2 Client(OAuth2客户端)是指使用OAuth2协议与授权服务器进行通信并获取访问令牌的应用程序或服务。OAuth2客户端代表最终用户(资源拥有者)向授权服务器请求授权,并使用授权后的

    2024年02月03日
    浏览(93)
  • SpringCloud整合spring security+ oauth2+Redis实现认证授权

    在微服务构建中,我们一般用一个父工程来通知管理依赖的各种版本号信息。父工程pom文件如下: 在SpringCloud微服务体系中服务注册中心是一个必要的存在,通过注册中心提供服务的注册和发现。具体细节可以查看我之前的博客,这里不再赘述。我们开始构建一个eureka注册中

    2024年02月06日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包