华为账号一键登录

服务端实现华为账号一键登录,需通过前端上传的授权码,在服务器获取华为用户信息实现登录业务逻辑。

一、获取用户凭证access_token

使用POST方式对api <https://oauth-login.cloud.huawei.com/oauth2/v3/token> 发起请求
参数为华为后台提供的应用idclient_id与密钥client_secret 客户端上传的授权码codegrant_type参数固定为authorization_code

注意请求头信息Content-Type为application/x-www-form-urlencoded

php请求示例

引用guzzlehttp包

// 使用guzzlehttp
composer require guzzlehttp/guzzle

发起POST请求,成功获取access_token后应该在过期时间内缓存起来,避免重复请求消耗接口请求次数,增加失败情况后的重试机制。

use GuzzleHttp\Client;

$code = '客户端上传的授权码';
$clientId = '应用id';
$secret = '应用密钥';

$options = [
    'http_errors' => false,
    'timeout' => 5,
    'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
    'form_params' => [
        'client_id' => $clientId,
        'client_secret' => $secret,
        'code' => $code,
        'grant_type' => 'authorization_code'
    ]
];

try {
    $guzzle = new Client();
    $response = $guzzle->post('https://oauth-login.cloud.huawei.com/oauth2/v3/token', $options);
    $result = json_decode($response->getBody()->getContents(), true);
} catch (Exception $e) {
   // 异常处理
}

// access_toke进行缓存,有效期为1小时,提供失败刷新机制

成功响应结果

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token": "<Access Token>",
    "refresh_token": "<Refresh Token>",
    "expires_in": 3600,
    "id_token": "<ID Token>",
    "scope": "openid profile email",
    "token_type": "Bearer"
}

失败响应结果

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8

{
    "sub_error": 12304,
    "error_description": "invalid client_secret",
    "error": 1101
}

二、获取用户信息

使用POST方式对api <https://account.cloud.huawei.com/rest.php?nsp_svc=GOpen.User.getInfo>发起请求,参数为上一步获取的access_token,成功获取到用户信息后,使用授权用户的手机号或unionid进行应用登录。

注意请求头信息Content-Type为application/x-www-form-urlencoded

请求示例

$options = [
    'http_errors' => false,
    'timeout' => 5,
    'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
    'form_params' => [
        'access_token' => $token,
    ]
];

try {
    $guzzle = new Client();
    $response = $guzzle->post('https://account.cloud.huawei.com/rest.php?nsp_svc=GOpen.User.getInfo', $options);
    $result = json_decode($response->getBody()->getContents(), true);
} catch (Exception $e) {
    // 异常处理
}

// 使用手机号进行注册或登录逻辑
$mobile = $result['mobileNumber']

成功响应结果

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "displayName": "182******74",
    "displayNameFlag": 1,
    "mobileNumber": "18211111174",
    "openID": "MDFAMTAxMDA1MTg1QGFlMzM0OWIyOGY0*****MDRiaNTI5ODAxYTA3MDh*****A4ZTZmNTA2ZTE4ZT*****lmNGVmN2E1ZjY1OTg4NWRiaN2QxMzQy*****TU0YWQ3",
    "unionID": "MDF9pBd6xxxxA8iaG4ZNPTw*****3fyXzG9WgUcmY8XibBvQ",
    "headPictureURL": "https://upfile-*****.jpg"
}

失败响应结果

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "error": "session timeout"
}

鸿蒙推送


客户端上报token, 使用token进行业务消息推送到客户端。

一、生成服务账号的鉴权令牌

令牌为JWT格式,包含Header(头部)Payload(负载)Signature(签名)三部分组成。

1.创建服务密钥文件(需要在华为开发者联盟上创建并下载推送服务API的服务账号密钥文件)

{
    "project_id": "*****",
    "key_id": "*****",
    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCKw6kJKtCh7qmMvp1u1dI27z2TKZrPOzHbQaXO/Eez0AWZ2EN+ouF496R3pfo7fQXC1XOT/YTbVC4DNZwWSMA54fu3/AOCY9Zzyi46OK*****==\n-----END PRIVATE KEY-----\n",
    "sub_account": "*****",
    "auth_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize",
    "token_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/token",
    "auth_provider_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/certs",
    "client_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/x509?client_id=*****"
}

2.生成JWT Header信息,kid为账号密钥文件中的key_id

{
  "kid": "*****",
  "typ": "JWT",
  "alg": "PS256"
}

3.生成JWT Payload数据,iss为服务账号密钥文件中sub_account字段,iat为当前时间戳 expiat晚3600秒

{
  "aud": "https://oauth-login.cloud.huawei.com/oauth2/v3/token",
  "iss": "*****",
  "exp": 1581410664,
  "iat": 1581407064
}

4.生成JWT Signature签名

将完成BASE64编码后的Header字符串与Payload字符串,通过“.”进行连接,通过服务密钥文件中的private_key使用SHA256withRSA/PSS算法对拼接的字符串签名。

php代码示例

$header = base64UrlEncode(json_encode([
    'kid' => '<key_id>',
    'typ' => 'JWT',
    'alg' => 'PS256'
]));
$payload = base64UrlEncode(json_encode([
    'aud' => 'https://oauth-login.cloud.huawei.com/oauth2/v3/token',
    'iss' => '<sub_account>',
    'exp' => time() + 3600,
    'iat' => time()
]));

// Load the RSA private key
$privateKeyResource = openssl_pkey_get_private($privateKey);
if (!$privateKeyResource) {
    die("Failed to load private key.");
}

$unsignedToken = $header . '.' . $payload;

// 签名
openssl_sign($unsignedToken, $signature, $privateKeyResource, 'sha256WithRSAEncryption');

// 拼接jwt
$token = $unsignedToken . '.' . $signature;



// base64编码
function base64UrlEncode($data)
{
    return \str_replace('=', '', \strtr(\base64_encode($data), '+/', '-_'));
}

二、消息推送请求

使用POST方式对api https://push-api.cloud.huawei.com/v3/[projectId]/messages:send发起请求,[projectId]在请求中替换实际项目id,增加头信息使用上一步获取的jwt鉴权令牌,并进行拼接,格式为:Authorization:Bearer <token>

注意请求头信息Content-Type为application/json

推送消息内容格式具体参与官方文档与示例:[<a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/push-scenariozed-api-request-param-V5">官方文档</a>] [<a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/push-scenariozed-api-request-example-V5">示例</a>]

php代码示例

$jwt = '<jwt令牌>';
$pushType = 0 //消息类型 0:Alert消息(通知消息、授权订阅消息)1:卡片刷新消息 2:通知扩展消息 6:后台消息 7:实况窗消息 10:应用内通话消息
$projectId = "<项目ID>"
$token = "<用户token>";

// 推送内容
$payload = [
    'notification' => [
        'category' => 'MARKETING',
        'title' => '消息标题',
        'body' => '消息描述',
        'clickAction' => ['actionType' => $actType]
    ]
];

// target最大支持10000个token
$body = [
    'payload' => $payload,
    'target' => [
        'token' => [$token]
    ]
];

$options = [
    'headers' => [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer ' . $jwt,
        'push-type' => $type
    ],
    'http_errors' => false,
    'timeout' => 5.0,
    'json' => $body,
];

try {
    $client = new Client();
    $resp = $client->post(sprintf('https://push-api.cloud.huawei.com/v3/%s/messages:send', $projectId), $options);
    if ($resp->getStatusCode() != 200) {
        return;
    }
    // 响应结果
    $content = json_decode($resp->getBody()->getContents(), true);
    if ($content['code'] != '80000000') {
        //失败情况处理
    }
catch (Exception $e) {
    // 异常处理
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容