ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何用oauth4cj扩展新的授权服务器:10分钟手写一个自定义API类

如何用oauth4cj扩展新的授权服务器:10分钟手写一个自定义API类 如何用oauth4cj扩展新的授权服务器10分钟手写一个自定义API类【免费下载链接】oauth4cj一个Oauth开放授权协议库Open Authorization的缩写项目地址: https://gitcode.com/Cangjie-TPC/oauth4cjoauth4cj 是一个支持 OAuth 1.0 和 OAuth 2.0 的 Cangjie 开源授权协议库允许第三方程序通过访问令牌访问受保护资源而无需暴露用户凭据。想接入 Gitee、GitHub、微博、华为等任意授权服务器本文带你10 分钟手写一个自定义 API 类把任何 OAuth 授权服务器接入 oauth4cj 的授权码、密码、客户端、简化四种模式全程只需继承一个基类、实现几个方法。上图展示了 oauth4cj 遵循的标准 OAuth 授权流程客户端Application向用户发起授权请求经授权服务器Authorization Server颁发访问令牌Access Token最终调用资源服务器Resource Server获取受保护资源。你要做的就是告诉 oauth4cj 你的授权服务器端点在哪里、怎么认证、令牌怎么解析——这正是自定义 API 类要回答的 4 个问题。为什么扩展新授权服务器只需要写一个类oauth4cj 采用默认实现 策略扩展的设计oauth_service.cj 定义了 OAuth 服务的公共骨架请求执行、关闭、HTTP 客户端等default_api20.cj 是OAuth 2.0 的扩展基类已内置绝大多数默认行为你只需继承它把每个平台不同的部分填上即可。基类中必须实现abstract的方法只有 2 个其余方法都提供了默认实现按需覆盖方法作用默认实现getAccessTokenEndpoint()令牌请求端点 URL❌ 必须实现getAuthorizationBaseUrl()用户授权页面 URL❌ 必须实现getAccessTokenVerb()令牌请求的 HTTP 方法✅ 默认 POSTgetRefreshTokenEndpoint()刷新令牌端点✅ 默认同令牌端点getClientAuthentication()客户端身份认证方式✅ 默认 HTTP BasicgetBearerSignature()access_token 附加到请求的位置✅ 默认放在 HeadergetAccessTokenExtractor()解析令牌响应体✅ 默认 JSON 解析getDeviceAuthorizationEndpoint()设备授权端点RFC 8628❌ 不支持则抛异常 规律总结一个平台的 OAuth 文档里通常只写 4 个信息——授权 URL、令牌 URL、认证方式、响应格式。这 4 个信息恰好对应上表的 4 个方法。10分钟手写自定义API类完整步骤第 1 步阅读目标平台的 OAuth 文档打开你的授权服务器下例假设是某平台oauth.example.com的开发者文档抄下 4 个信息授权页面https://oauth.example.com/authorize令牌端点https://oauth.example.com/oauth/tokenPOST客户端认证client_id/client_secret放在请求体中令牌响应标准 JSONaccess_token、expires_in、refresh_token…第 2 步继承 DefaultApi20 写你的 API 类只需 30 行代码对照 default_api20.cj 的方法签名/* * 准备 OAuth 2.0 的默认实现 * 继承 DefaultApi20实现抽象方法覆盖不同的提取器或服务。 */ public class ExampleApi : DefaultApi20 { protected init() { } public static func instance(): ExampleApi { return ExampleApi() } //返回请求类型默认就是 POST这里显式写出让读者直观 public func getAccessTokenVerb(): Verb { return Verb.POST } //接收访问令牌请求的 URL public func getAccessTokenEndpoint(): String { return https://oauth.example.com/oauth/token } //用户授权页面链接 protected func getAuthorizationBaseUrl(): String { return https://oauth.example.com/authorize } //客户端认证client_id/client_secret 写入请求主体 public func getClientAuthentication(): ClientAuthentication { return RequestBodyAuthenticationScheme.instance() } //access_token 通过 URI 查询参数附加到请求中 public func getBearerSignature(): BearerSignature { return BearerSignatureURIQueryParameter.instance() } }注意两点getAccessTokenExtractor()不用写——默认返回 OAuth2AccessTokenJsonExtractor绝大多数平台返回的都是标准 JSON你的平台若要求 token 放在 HeaderAuthorization: Bearer xxx则getBearerSignature()可省略默认即是该行为见 bearer_signature.cj。第 3 步用 ServiceBuilder 构建服务在 service_builder_oauth20.cj 的建造者模式中把自定义 API 类作为build()参数传入let service: OAuth20Service ServiceBuilderOAuth20(clientId). setApiSecret(clientSecret). setDefaultScope(profile emails). setCallback(redirect_uri). build(ExampleApi.instance()) // 关键注入自定义 API 类第 4 步跑通授权码模式以 oauth20_service.cj 的接口为例//1. 生成可获取授权码的链接 let authorizationUrl: String AuthorizationUrlBuilder(service). setState(secret).build() //2. 用回调拿到的一次性授权码 code换取访问令牌 let accessToken: OAuth2AccessToken service.getAccessToken(code) //3. 签名并请求受保护资源 let request: OAuth4cjRequest OAuth4cjRequest(Verb.GET, protectedResourceUrl) service.signRequest(accessToken, request) let response: OAuth4cjResponse service.execute(request)至此你的授权服务器已完整接入。其他模式同样直接可用密码模式service.getAccessTokenPasswordGrant(username, password)客户端模式service.getAccessTokenClientCredentialsGrant()刷新令牌service.refreshAccessToken(accessToken.getRefreshToken())设备授权RFC 8628覆盖getDeviceAuthorizationEndpoint()后调用service.getDeviceAuthorizationCodes()平台差异速查该覆盖哪个方法平台差异需要覆盖的方法令牌响应不是 JSON如简化模式返回access_tokenxxxexpires_inxxx纯文本getAccessTokenExtractor()参考 oauth2_access_token_extractor.cj刷新令牌端点独立于令牌端点getRefreshTokenEndpoint()支持令牌吊销RFC 7009getRevokeTokenEndpoint()令牌请求要求 GET如腾讯简化模式getAccessTokenVerb()返回Verb.GET支持设备授权授予RFC 8628getDeviceAuthorizationEndpoint()官方文档中的 Gitee、华为、腾讯示例就是同一套模板的不同填法可直接在 README.md 的功能示例章节对照阅读。常见问题Q1自定义 API 类要单例吗不是必须但示例代码统一提供了static func instance()方便复用。Q2OAuth 1.0a 平台怎么扩展同样思路继承 default_api10a.cj 基类用 service_builder_oauth10a.cj 构建服务。Q3请求失败报 401 通常是哪里出了问题优先检查getClientAuthentication()与平台要求的认证方式是否一致Body 传参 vs HTTP Basic 头。参考资料完整接口说明doc/feature_api.md各平台功能示例与编译构建说明README.md版本变更记录CHANGELOG.md动手试试吧找到你常用的一个授权平台的 OAuth 文档照上表填 4 个信息10 分钟后你就会得到一个能跑通授权码模式的自定义 API 类。【免费下载链接】oauth4cj一个Oauth开放授权协议库Open Authorization的缩写项目地址: https://gitcode.com/Cangjie-TPC/oauth4cj创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表