切换语言为:繁体
Vue 实现接入第三方 Apple 登录方案

Vue 实现接入第三方 Apple 登录方案

  • 爱糖宝
  • 2024-09-26
  • 2056
  • 0
  • 0

开发者账号配置

申请一个Apple开发者账号

开发者账号配置

在web端接入Apple登录前,需要进行相关信息的配置。具体配置可以参照 配置的流程,或者 Apple的开发者文档

配置生成后,我们会得到一系列的配置信息和文件

两个ID

  • App ID & Services ID

两个文件

  • apple-developer-domain-association.txt

    • 作为账号配置过程中验证的作用;

    • 放在项目的根目录,通过 https://域名/.well-known/apple-developer-domain-association.txt 可访问其中内容;

    • 完成后点击 Apple开发者账号配置过程中的验证按钮,验证通过后可进行正常的开发调试,后续可以删除此文件。

  • 一个以.p8结尾的文本文件,里面是生成的密钥,用作生成JWT,作为请求Token时的参数之一

流程说明

常规登录流程

  1. 获取 client_id,注册一个前端的 redirect_uri

  2. 调用登录时,跳转到 Apple 页面去授权

  3. 用户授权成功后,url 中带着 code 和其他的参数重定向回到前端页面

  4. 前端页面获取 code & idToken,调用服务端的 API并传递参数 code 和 jwt 解析后 idToken 得到 sub

  5. 服务端获取 code & sub 向 Apple 服务器交互

Apple实际登录流程

  1. 获取 client_id,注册一个服务端的 redirect_uri

  2. 调用登录时,跳转到 Apple 页面去授权

  3. 用户授权成功后,Apple 用表单提交 code和其他参数 到重定向 url

  4. 服务端获取 code和其他参数,通过302跳转到前端页面

  5. 前端页面获取 code & idToken,调用服务端的 API 并传递参数 code 和 jwt 解析后 idToken 得到 sub

  6. 服务端获取 code & sub 向 Apple 服务器交互

流程图

Vue 实现接入第三方 Apple 登录方案


接入登录流程

前端选用 Sign in with Apple JS 的方式接入Apple的登录

嵌入使用 Apple JS 登录

在您的网页中包含脚本标签并链接到 Apple 托管的使用 Apple 登录 JS 框架的版本:

<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>

配置授权对象

通过在标头部分设置元标记

<head>
    <meta name="appleid-signin-client-id" content="[CLIENT_ID]">
    <meta name="appleid-signin-scope" content="[SCOPES]">
    <meta name="appleid-signin-redirect-uri" content="[REDIRECT_URI]">
    <meta name="appleid-signin-state" content="[STATE]">
    <meta name="appleid-signin-nonce" content="[NONCE]">
    <meta name="appleid-signin-use-popup" content="true">
</head>

使用JS API配置授权对象

<script type="text/javascript">
    AppleID.auth.init({
        clientId: '[CLIENT_ID]',
        scope: '[SCOPES]',
        redirectURI: '[REDIRECT_URI]',
        state: '[STATE]',
        nonce: '[NONCE]',
        responseType: '[RESPONSE_TYPE]'
        responseMode: '[RESPONSE_MODE]'
        usePopup: true
    });
</script>

配置授权对象参数解析

  • clientId - 对应开发者账号配置生成的 Serivces ID

  • scope - 授权范围,可以是nameemail 或者 name email

  • redirectURI - 重定向 URI,是 Apple ID 认证完成后重定向到的 URI

  • state - 状态,一个随机字符串,用于防止 CSRF 攻击

  • nonce - 一个随机字符串,用于防止重放攻击

  • responseType - 响应类型,可以是 codetoken

    • code: 授权码模式,Apple ID 认证完成后返回一个授权码,客户端需要使用该授权码换取访问令牌

    • token: 隐式模式,Apple ID 认证完成后直接返回一个访问令牌,客户端可以直接使用该令牌访问受保护的资源

  • responseMode - 响应模式,可以是 form_postfragment 或者 query

    • form_post: 表单提交模式,Apple ID 认证完成后将授权码或访问令牌通过表单提交返回

    • fragment: URL片段模式,Apple ID 认证完成后将授权码或访问令牌通过URL片段返回

    • query: 查询字符串模式,Apple ID 认证完成后将授权码或访问令牌通过查询字符串返回

  • usePopup - 是否使用弹窗模式,默认为 false

登录按钮构建

可以参照开发者文档,配置属性显示按钮。登录按钮属性配置

<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>

也可以根据业务需求,通过CSS自定义登录按钮样式

触发登录

走 Apple 登录之前,必须先调用 AppleID.auth.init 方法去初始化 Apple ID 认证。不然 SDK 会报错误信息:

Vue 实现接入第三方 Apple 登录方案

初始化 Apple ID 认证后,后续可以调用 AppleID.auth.signIn 进行 Apple ID 登录。

编码

<template>
</template>
<script>
export default {
  name: 'AppleLogin',
  created () {
    this.initAppleLogin()
  },
  methods: {
    // 初始化 Apple ID 认证
    initAppleLogin () {
      if (AppleID?.auth) {
        const nonce = Math.random().toString(36).substr(2, 10);
        AppleID.auth.init({
          clientId: '',
          redirectURI: '',
          responseType: '',
          scope: '',
          state: '',
          responseMode: '',
          nonce,
        });
      }
      this.signInAppleLogin()
    },
    
    // 调用 Apple ID 登录
    signInAppleLogin () {
      try {
        AppleID.auth.signIn()
      } catch ( error ) {
        console.error(' Apple Sign In Error: ', error);
      }
    },
  }
}
</script>

code获取

服务端302重定向到前端的 url 的格式:http://前端指定的路由?code=&idToken=&state=&user=

前端需要通过JWT解析idToken

这个 idToken 包含了用户的信息,例如用户名,邮箱等。
然而,这个 idToken 是被 Apple 通过 JWT 加密过的,需要解密后拿到其中的 sub 属性值去跟 Apple 服务器换取信息

jwt使用

jwt-decode参考

// 安装
npm i -S jwt-decode

// 使用
import { jwtDecode } from "jwt-decode";
const token = "eyJ0eXAiO...";
const decoded = jwtDecode(token);
 
/**
{
    "iss": "https://appleid.apple.com",
    "aud": "",
    "exp": ,
    "iat": ,
    "sub": "",
    "nonce": "",
    "c_hash": "",
    "email": "",
    "email_verified": ,
    "is_private_email": ,
    "auth_time": ,
    "nonce_supported": 
}
*/

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.