`

Sign in with Apple REST API (Rails)

阅读更多

# 文档(Apple授权登录)

https://developer.apple.com/documentation/signinwithapplerestapi

# 获取公钥Key接口

https://appleid.apple.com/auth/keys

# 验证客户端发送的authorizationCode接口

https://appleid.apple.com/auth/token

 

 

require 'net/https'
require 'jwt'

class AppleAuth
    APPLE_ISSUER = 'https://appleid.apple.com'.freeze
    APPLE_CONFIG = {
      client_id:   ENV['CLIENT_ID'], # com.mytest.app
      key_id:      ENV['KEY_ID'], # 10位字符
      team_id:     ENV['TEAM_ID'], # 10位字符
      # Apple官方配置好下载下来文件内容
      private_key: ENV['PRIVATE_KEY'] # -----BEGIN PRIVATE KEY----- *** 
    }

    class << self
      def public_keys # 获取公钥keys
        uri = URI(File.join(APPLE_ISSUER, '/auth/keys'))
        res = Net::HTTP.get_response(uri)
        if res.code.to_i == 200
          JSON.parse(res.body)['keys']
        end
      end

      def jwt_token_info(jwt_token, key, verify, opts = {})
        payload, header = JWT.decode(jwt_token, key, verify, opts)
        {payload: payload, header: header}.stringify_keys
      end
    end

    # token:identityToken
    # auth_code:authorizationCode
    # opts.email 客户端email
    # opts.apple_uid: userId 信息
    # opts.idfa_str: IDFAStr 信息
    # opts.family_name
    # opts.given_name
    def initialize(token, auth_code, opts = {})
      @client_token = token
      @auth_code    = auth_code
      @opts         = opts.stringify_keys
    end

    # JWT 验证方式
    def jwt_verify?(opts = {})
      valid_token_info(opts).present?
    end
    
    def client_token_info # 得到Token内容时没有验证
      @_client_token_info = self.class.jwt_token_info(@client_token, nil, false)
    end

    def valid_token_info(opts = {}) # 验证通过得到Token内容
      opts.merge!(algorithm: client_token_info.dig('header', 'alg'))
      self.class.jwt_token_info(@client_token, public_key.keypair, true, opts)
    rescue
      {}
    end

    def auth_token_info # 通过/auth/token获取的id_token解析的信息
      res = cache_apple_code_auth
      self.class.jwt_token_info(res['id_token'], nil, false)
    end

    private

    def public_key(force = false) # 获取解析Token的对应公钥
      if @_public_key && !force
        @_public_key
      else
        if (_keys = self.class.public_keys)
          key          = _keys.find { |obj| obj['kid'] == client_token_info.dig('header', 'kid') }
          @_public_key = JWT::JWK.import(key.symbolize_keys) if key
        end
      end
    end

    def code_verify_params # 构建请求/auth/token的参数
      {
        grant_type:    'authorization_code',
        client_id:     APPLE_CONFIG[:client_id],
        client_secret: client_secret,
        code:          @auth_code,
      }
    end

    def client_secret
      payload   = {
        iss: APPLE_CONFIG[:team_id],
        iat: Time.current.to_i,
        exp: 10.minutes.after.to_i,
        aud: APPLE_ISSUER,
        sub: APPLE_CONFIG[:client_id]
      }
      header    = {
        # alg: 'ES256', 加上请求失败 "error"=>"invalid_request"
        kid: APPLE_CONFIG[:key_id]
      }
      ecdsa_key = OpenSSL::PKey::EC.new(APPLE_CONFIG[:private_key])

      JWT.encode(payload, ecdsa_key, 'ES256', header)
    end

    def cache_apple_code_auth(force = false)
      uri = URI(File.join(APPLE_ISSUER, '/auth/token'))
      res = Net::HTTP.post_form(uri, code_verify_params)
        if res.code == 200
          JSON.parse(res.body)
        else
          {}
        end
    end
  end

 

 

 

分享到:
评论

相关推荐

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...

    rails api(文档)

    Rails API 是一个专门为构建应用程序接口(API)设计的Ruby on Rails框架版本。它专注于提供一套轻量级的工具,使得开发者能够快速、高效地创建RESTful API服务。Rails API的目的是为了提高性能,并减小API服务器与...

    应用Rails进行REST开发

    ### 应用Rails进行REST开发 #### 1.1 什么是REST? REST(Representational State Transfer),这是一种由Roy Fielding在他的博士论文中提出的架构风格。REST的核心思想是通过标准HTTP协议中的GET、POST、PUT、...

    rails-api-4.0.0

    《Rails API 4.0.0:Ruby on Rails框架的API设计与开发指南》 Rails API 4.0.0是Ruby on Rails框架的一个版本,专门针对构建应用程序接口(APIs)进行了优化。Ruby on Rails是由David Heinemeier Hansson创建的开源...

    railsAPI

    Rails API 是一个强大的框架,用于构建高效、可扩展的Web应用程序。它基于Ruby编程语言,遵循MVC(模型-视图-控制器)架构模式,使得开发者可以轻松地处理数据存储、用户界面和业务逻辑。Rails API 特别适用于构建...

    mage-rest-on-rails:Magento 的 REST API on Rails 4 的简单示例

    Rails 4 上的 Magento REST API Magento 在 Rails 4 上的 REST API 的一个简单示例,其中还包括基准测试 + oauth 注释。安装克隆这个 repo 运行bundle install 运行rails server配置您需要修改的唯一文件是settings/...

    跨越边界:REST on Rails

    Ruby on Rails是一个突然流行...本文介绍Rails中的Web服务,重点放在一个名为Representational State Transfer (REST)的策略上。本文介绍了如何在Ruby on Rails中添加REST风格的Web服务,并从Ruby和Java代码调用服务。

    ruby on rails api

    标题“ruby on rails api”表明我们将讨论的是Rails框架的API(Application Programming Interface),这是一系列预先定义好的函数、类和模块,允许开发者通过调用来实现特定的功能,无需从头编写所有代码。Rails ...

    Agile Web Development with Rails 4

    We still start with a step-by-step walkthrough of building a real application, and in-depth chapters look at the built-in Rails features. This edition now gives new Ruby and Rails users more ...

    Agile+Web+Development+with+Rails中文版.pdf

    《Agile Web Development with Rails》是一本经典的Rails开发指南,中文版的出版使得更多的中国开发者能够深入理解并应用敏捷开发方法与Ruby on Rails框架。这本书是Rails开发者的必备参考资料,它详细介绍了如何...

    ruby on rails 2.3.5 api html版

    Ruby on Rails 2.3.5 API HTML版是针对该版本框架的重要开发参考资料,它包含了详细的API文档,帮助开发者理解并有效地使用Rails 2.3.5进行Web应用开发。Rails是一个基于Ruby语言的开源Web应用程序框架,它遵循模型-...

    rails_5_api_tutorial:使用Swagger UI构建Perfect Rails 5 API Only应用程序并记录基于Rails的REST API

    构建Perfect Rails 5 API Only应用得益于作为Rails 5核心一部分提供的新的rails-api gem,Rails现在是快速,轻松构建精简API的理想选择。 到目前为止,可以说,在Ruby中创建API的最佳选择是Grape,尽管Grape仍然是一...

    rails 3.2 API

    Rails 3.2 API 是一个重要的开发资源,主要用于Ruby on Rails框架的开发。Rails是基于Ruby语言的一个开源Web应用程序框架,遵循MVC(Model-View-Controller)架构模式,广泛应用于构建动态网站和Web应用程序。Rails ...

    rails-api

    个人收藏的rails api

    Rails API

    **Ruby on Rails API** 是一个详尽的文档资源,它为开发者提供了关于Ruby on Rails框架的全面信息。这个API文档是用rdoc工具从Rails的源代码生成的,旨在帮助开发者理解和利用Rails的强大功能。CHM(Compiled ...

    rails api

    rails的api文档,方便你查看

    google_sign_in:使用Google for Rails应用程序登录(或注册)

    安装将google_sign_in添加到您的Rails应用的Gemfile并运行bundle install : gem 'google_sign_in' 要使用Rails进行Google登录,需要安装Rails 5.2或更高版本。组态首先,在Google API控制台中设置OAuth 2.0客户端ID...

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    rails 2.2.2 API

    Rails 2.2.2 API 是一个针对 Ruby on Rails 框架的版本 2.2.2 的接口文档,它是开发人员的重要参考资料,用于理解并有效地使用该框架的各项功能。Ruby on Rails(RoR)是由 David Heinemeier Hansson 创建的一个开源...

Global site tag (gtag.js) - Google Analytics