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

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

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

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

python 复制代码
@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:

python 复制代码
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 登录

javascript 复制代码
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了

相关推荐
Csvn29 分钟前
运行时性能
前端
冬奇Lab29 分钟前
一天一个开源项目(第247篇):wxa-runner —— 让小程序在普通浏览器里用微信官方基础库跑起来,直接接 Playwright 做无头 E2E
微信小程序·开源
supabc1231 小时前
欧盟电子发票(XRechnung/Peppol/ZUGFeRD)踩坑记:用 Python 不装 Java 跑官方校验规则
xml·python·开源·电子发票·1024程序员节
Never_every991 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
ZhengEnCi1 小时前
AI Agent工具调用防护层怎么写-一份能直接跑的Python四层拦截实现
python·llm·agent
paopaokaka_luck2 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
ZhengEnCi2 小时前
AI Agent工具误调用怎么解决-从参数校验到高危二次确认的四层工程防线
python·llm·agent
andrsted2 小时前
练题簿在线免费刷题:让整理过的资料,变成能反复练习的题库
学习·微信小程序·小程序·学习方法·刷题·1024程序员节
空中湖2 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
悟空码字3 小时前
视频号直播变了
微信·视频号