微信多端app开发之苹果登录集成教程(WebView 示例)

发布于:2024-12-06 ⋅ 阅读:(46) ⋅ 点赞:(0)

在这篇教程中,我们将介绍如何在多端(如微信小程序、移动应用等)实现 Apple OAuth 登录,并提供简单的代码示例。

  1. 1.回调处理 - 获取授权码并交换令牌

        当用户授权后,Apple 会回调你设置的 URL(如 apple_callback/)。后端会接收授权码并请求令牌。

@skip_jwt_authentication
def apple_callback(request):
    """
    Apple OAuth 回调处理
    """
    code = request.POST.get('code')  # 获取授权码
    if not code:
        return JsonResponse({'code': 4003, 'message': "缺少授权码"}, status=400)

    # 请求 Apple token
    client_secret = generate_apple_client_secret()  # 生成 client_secret
    token_url = "https://appleid.apple.com/auth/token"
    token_data = {
        'client_id': settings.APPLE_CLIENT_ID,
        'client_secret': client_secret,
        'code': code,
        'grant_type': 'authorization_code',
        'redirect_uri': settings.APPLE_REDIRECT_URI,
    }

    try:
        token_response = requests.post(token_url, data=token_data)
        token_response.raise_for_status()  # 如果请求失败,会抛出异常

        # 解析 token
        token_info = token_response.json()
        id_token = token_info.get('id_token')

        if not id_token:
            return JsonResponse({'code': 4004, 'message': '未收到 id_token'}, status=400)

        # 解码 id_token 并提取信息
        decoded_id_token = jwt.decode(
            id_token,
            get_apple_public_key(id_token),
            audience=settings.APPLE_CLIENT_ID,
            issuer="https://appleid.apple.com",
            algorithms=["RS256"]
        )

        apple_user_id = decoded_id_token.get('sub')
        email = decoded_id_token.get('email')

        # 查找或创建用户
        user, created = CustomUser.objects.get_or_create(
            apple_id=apple_user_id,
            defaults={'email': email, 'is_active': False}  # 默认信息
        )

        # 返回 JWT token 和用户信息
        jwt_token = JWTAuthentication.generate_jwt_token(user)
        user_data = user.get_user_profile_data()
        profile_complete = user.is_active

        return render(request, 'app/apple_success.html', {
            'jwt_token': jwt_token,
            'userInfo': json.dumps(user_data),
            'profile_complete': json.dumps(profile_complete)
        })

    except requests.exceptions.RequestException as e:
        return JsonResponse({'code': 5001, 'message': 'Apple token 请求失败'}, status=500)
    except jwt.exceptions.InvalidTokenError as e:
        return JsonResponse({'code': 4006, 'message': 'id_token 解码失败'}, status=400)

  2.用于验证 id_token: 

def generate_apple_client_secret():
    """
    生成 Apple OAuth 2.0 client_secret
    """
    headers = {
        "alg": "ES256",
        "kid": settings.APPLE_KEY_ID  # 替换为你的 APPLE_KEY_ID
    }
    payload = {
        "iss": settings.APPLE_TEAM_ID,  # 替换为你的 APPLE_TEAM_ID
        "iat": datetime.utcnow(),
        "exp": datetime.utcnow() + timedelta(days=180),
        "aud": "https://appleid.apple.com",
        "sub": settings.APPLE_CLIENT_ID  # 替换为你的 APPLE_CLIENT_ID
    }

    client_secret = jwt.encode(
        payload,
        settings.APPLE_PRIVATE_KEY,  # 替换为你的 APPLE_PRIVATE_KEY
        algorithm="ES256",
        headers=headers
    )
    return client_secret

def get_apple_public_key(id_token):
    """
    获取 Apple 公钥用于验证 id_token
    """
    try:
        apple_keys = requests.get("https://appleid.apple.com/auth/keys").json()
        headers = jwt.get_unverified_header(id_token)
        key = next((k for k in apple_keys['keys'] if k["kid"] == headers["kid"]), None)

        if key:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(key)
            return public_key
        else:
            raise ValueError("未找到匹配的 Apple 公钥")
    except Exception as e:
        raise ValueError("未找到匹配的 Apple 公钥")

 3.前端 - 启动 WebView 打开 Apple 登录

appleLogin() {
    console.log("Apple 登录触发");

    // 构建 Apple 登录 URL
    const appleLoginUrl = `https://appleid.apple.com/auth/authorize?client_id=客户端ID 在苹果开发者后台找到&redirect_uri=https://回调域名/&response_type=code&scope=name email&state=random_string_to_ensure_request_integrity&response_mode=form_post`;

    // 使用 WebView 打开 Apple 登录页面
    app.openWebViewPage(appleLoginUrl);
}

需要填写的内容:

  • client_id:替换为你的 Apple 客户端 ID。
  • redirect_uri:替换为你的回调 URL,通常是处理授权码的后端接口 URL。

总结

通过以上步骤,你可以实现 Apple 登录功能。后端负责生成认证 URL 和处理回调,前端通过 WebView 跳转到认证页面,用户认证后,后端接收授权码并交换令牌,最终完成用户登录过程。

在ios设备上就实现一点击出现人脸识别就可以登录你的app了


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章