HarmonyOS 第三方登录之QQ登录

2025-05-29 0 56

HarmonyOS 第三方登录之QQ登录

前言

因为鸿蒙系统刚出不久,官方的第三方登录SDK还没出来,下面就介绍下在鸿蒙应用中实现QQ登录的方法(支持唤起QQ安卓客户端进行授权)

前期准备

登录QQ开放平台 > 应用管理 > 创建应用 ,创建一个网站应用。

注意:要选择网站应用,移动应用和小程序不适用该方案。

编写代码

判断是否已登录

获取登录状态

在入口AbilitySliceMainAbilitySlice中进行判断。

从数据库获取token的值判断是否已经登录账号 (已登录返回token,未登录返回null)

  1. // 创建数据库(这里使用官方提供的“轻量级数据存储”,相关文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-preference-guidelines-0000000000030083)
  2. Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences(\”DATA_NAME\”);
  3. // 从数据库获取token的值判断是否已经登录账号 (已登录返回token,未登录返回null)
  4. String token = preferences.getString(\”token\”,null);

进行相应跳转

已登录跳转至个人界面MyAbility,未登录跳转至登录界面LoginAbility.

  1. if(token != null){
  2. // 已登录,跳转至MyAbility
  3. Intent myIntent = new Intent();
  4. myIntent.setParam(\”token\”, token);
  5. Operation myOperation = new Intent.OperationBuilder()
  6. .withBundleName(\”cn.dsttl3.test\”)
  7. .withAbilityName(\”cn.dsttl3.qqlogin.MyAbility\”)
  8. .build();
  9. myIntent.setOperation(myOperation);
  10. startAbility(myIntent);
  11. terminateAbility();
  12. }else {
  13. // 未登录,跳转至LoginAbility
  14. Intent loginIntent = new Intent();
  15. Operation loginOperation = new Intent.OperationBuilder()
  16. .withBundleName(\”cn.dsttl3.test\”)
  17. .withAbilityName(\”cn.dsttl3.qqlogin.LoginAbility\”)
  18. .build();
  19. loginIntent.setOperation(loginOperation);
  20. startAbility(loginIntent);
  21. terminateAbility();
  22. }

登录界面的操作

申请网络访问权限

在config.json添加

  1. \”reqPermissions\”: [
  2. {
  3. \”name\”: \”ohos.permission.INTERNET\”
  4. }
  5. ]

登录界面布局文件ability_login.xml

在布局文件中添加以后webview组件

  1. <?xml version=\”1.0\” encoding=\”utf-8\”?>
  2. <DIRECTIONALLAYOUT span
  3. xmlns:ohos=\”http://schemas.huawei.com/res/ohos\”
  4. ohos:height=\”match_parent\”
  5. ohos:width=\”match_parent\”
  6. ohos:alignment=\”center\”
  7. ohos:orientation=\”vertical\”>
  8. <OHOS.AGP.COMPONENTS.WEBENGINE.WEBVIEW span
  9. ohos:id=\”$+id:WebView_qqlogin\”
  10. ohos:height=\”match_parent\”
  11. ohos:width=\”match_parent\”/>

登录界面的AbilitySlice LoginAbilitySlice.java

需要用到的几个常量

  1. String state = UUID.randomUUID().toString();// 唯一标识,成功授权后回调时会原样带回。
  2. String client_id = \”101***151\”;//QQ开放平台 应用 APP ID
  3. String redirect_uri = \”https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin\”; //应用 网站回调域 需进行url编码,授权成功后会跳转至该链接
  4. String authorize_url = \”https://graph.qq.com/oauth2.0/authorize?response_type=code\” +
  5. \”&client_id=\” + client_id +
  6. \”&redirect_uri=\” + redirect_uri +
  7. \”&state=\”+ state;

WebView的配置

  1. WebView myWebView = (WebView) findComponentById(ResourceTable.Id_WebView_qqlogin);
  2. myWebView.getWebConfig().setJavaScriptPermit(true);//支持JavaScript
  3. myWebView.getWebConfig().setUserAgent(\”android\”);//将UserAgent设置为安卓,授权页才显示QQ客户端一键登录按钮

自定义WebAgent

当WebView即将打开一个链接时调用isNeedLoadUrl方法,当在网页上点击“一键登录”时,打开QQ客户端

wtloginmqq是QQ安卓客户端URL Scheme

  1. if (request.getRequestUrl().toString().startsWith(\”wtloginmqq\”)){
  2. // 打开QQ客户端
  3. Intent qqIntent = new Intent();
  4. Operation qqOperation = new Intent.OperationBuilder()
  5. .withAction(\”android.intent.action.VIEW\”)
  6. .withUri(Uri.parse(request.getRequestUrl().toString()))
  7. .build();
  8. qqIntent.setOperation(qqOperation);
  9. startAbility(qqIntent);

因为目前还找不到网页端唤起鸿蒙应用的方法,所以QQ客户端回调的code放在自己服务器处理。

授权成功后,会打开之前在QQ开放平台设置的回调域redirect_uri

示例:https://api.dsttl3.cn/Redis/QQLogin?code=********&state=*****

code:QQ授权返回的code,用于申请token

state:在webview请求QQ授权页面时传入的唯一标识,用于判断用户身份,方便后续从服务器请求token

出于安全考虑 ,请求token操作放在服务器上执行。获取到token后将token存入数据库,客户端通过请求https://api.dsttl3.cn/Redis/Get?key= + state来获取到token

客户端请求到token后,将token存储到数据库

  1. // 将token存入数据库
  2. Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences(\”DATA_NAME\”);
  3. preferences.putString(\”token\”,token);
  4. preferences.flush();

token存储完成后跳转至MyAbility

自定义WebAgent完整代码

  1. myWebView.setWebAgent(new WebAgent(){
  2. // 当WebView即将打开一个链接时调用该方法
  3. @Override
  4. public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) {
  5. // request.getRequestUrl().toString() WebView即将打开的链接地址
  6. if (request.getRequestUrl().toString().startsWith(\”wtloginmqq\”)){
  7. // 打开QQ客户端
  8. Intent qqIntent = new Intent();
  9. Operation qqOperation = new Intent.OperationBuilder()
  10. .withAction(\”android.intent.action.VIEW\”)
  11. .withUri(Uri.parse(request.getRequestUrl().toString()))
  12. .build();
  13. qqIntent.setOperation(qqOperation);
  14. startAbility(qqIntent);
  15. // 向自己的服务器请求token
  16. new Thread(new Runnable() {
  17. @Override
  18. public void run() {
  19. while (true){
  20. String getTokenURL = \”https://api.dsttl3.cn/Redis/Get?key=\” + state;
  21. try {
  22. OkHttpClient client = new OkHttpClient();
  23. Request request = new Request.Builder().url(getTokenURL).build();
  24. String token = client.newCall(request).execute().body().string();
  25. if (token.length() == 32){
  26. getUITaskDispatcher().asyncDispatch(new Runnable() {
  27. @Override
  28. public void run() {
  29. // 将token存入数据库
  30. Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences(\”DATA_NAME\”);
  31. preferences.putString(\”token\”,token);
  32. preferences.flush();
  33. // 跳转至用户界面
  34. Intent myIntent = new Intent();
  35. Operation myOperation = new Intent.OperationBuilder()
  36. .withBundleName(\”cn.dsttl3.test\”)
  37. .withAbilityName(\”cn.dsttl3.qqlogin.MyAbility\”)
  38. .build();
  39. myIntent.setOperation(myOperation);
  40. startAbility(myIntent);
  41. terminateAbility();
  42. }
  43. });
  44. break;
  45. }
  46. Time.sleep(1500);
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. }
  52. }).start();
  53. return false;
  54. }
  55. return true;
  56. }
  57. });

加载网页

  1. myWebView.load(authorize_url);

LoginAbilitySlice.java完整代码

  1. import cn.dsttl3.qqlogin.ResourceTable;
  2. import ohos.aafwk.ability.AbilitySlice;
  3. import ohos.aafwk.content.Intent;
  4. import ohos.aafwk.content.Operation;
  5. import ohos.agp.components.webengine.ResourceRequest;
  6. import ohos.agp.components.webengine.WebAgent;
  7. import ohos.agp.components.webengine.WebView;
  8. import ohos.data.DatabaseHelper;
  9. import ohos.data.preferences.Preferences;
  10. import ohos.miscservices.timeutility.Time;
  11. import ohos.utils.net.Uri;
  12. import okhttp3.OkHttpClient;
  13. import okhttp3.Request;
  14. import java.io.IOException;
  15. import java.util.UUID;
  16. public class LoginAbilitySlice extends AbilitySlice {
  17. //QQ开放平台登录授权文档 https://wiki.connect.qq.com/%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c_oauth2-0
  18. String state = UUID.randomUUID().toString();// 唯一标识,成功授权后回调时会原样带回。
  19. String client_id = \”101547151\”;//QQ开放平台 应用 APP ID
  20. String redirect_uri = \”https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin\”; //应用 网站回调域 需进行url编码,授权成功后会跳转至该链接
  21. String authorize_url = \”https://graph.qq.com/oauth2.0/authorize?response_type=code\” +
  22. \”&client_id=\” + client_id +
  23. \”&redirect_uri=\” + redirect_uri +
  24. \”&state=\”+ state;
  25. @Override
  26. public void onStart(Intent intent) {
  27. super.onStart(intent);
  28. super.setUIContent(ResourceTable.Layout_ability_login);
  29. WebView myWebView = (WebView) findComponentById(ResourceTable.Id_WebView_qqlogin);
  30. myWebView.getWebConfig().setJavaScriptPermit(true);
  31. myWebView.getWebConfig().setUserAgent(\”android\”);
  32. myWebView.setWebAgent(new WebAgent(){
  33. // 当WebView即将打开一个链接时调用该方法
  34. @Override
  35. public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) {
  36. // request.getRequestUrl().toString() WebView即将打开的链接地址
  37. if (request.getRequestUrl().toString().startsWith(\”wtloginmqq\”)){
  38. // 打开QQ客户端
  39. Intent qqIntent = new Intent();
  40. Operation qqOperation = new Intent.OperationBuilder()
  41. .withAction(\”android.intent.action.VIEW\”)
  42. .withUri(Uri.parse(request.getRequestUrl().toString()))
  43. .build();
  44. qqIntent.setOperation(qqOperation);
  45. startAbility(qqIntent);
  46. // 向自己的服务器请求token
  47. new Thread(new Runnable() {
  48. @Override
  49. public void run() {
  50. while (true){
  51. String getTokenURL = \”https://api.dsttl3.cn/Redis/Get?key=\” + state;
  52. try {
  53. OkHttpClient client = new OkHttpClient();
  54. Request request = new Request.Builder().url(getTokenURL).build();
  55. String token = client.newCall(request).execute().body().string();
  56. if (token.length() == 32){
  57. getUITaskDispatcher().asyncDispatch(new Runnable() {
  58. @Override
  59. public void run() {
  60. // 将token存入数据库
  61. Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences(\”DATA_NAME\”);
  62. preferences.putString(\”token\”,token);
  63. preferences.flush();
  64. // 跳转至用户界面
  65. Intent myIntent = new Intent();
  66. Operation myOperation = new Intent.OperationBuilder()
  67. .withBundleName(\”cn.dsttl3.test\”)
  68. .withAbilityName(\”cn.dsttl3.qqlogin.MyAbility\”)
  69. .build();
  70. myIntent.setOperation(myOperation);
  71. startAbility(myIntent);
  72. terminateAbility();
  73. }
  74. });
  75. break;
  76. }
  77. Time.sleep(1500);
  78. } catch (IOException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. }
  83. }).start();
  84. return false;
  85. }
  86. return true;
  87. }
  88. });
  89. myWebView.load(authorize_url);
  90. }
  91. }

个人界面

获取token信息

  1. Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences(\”DATA_NAME\”);
  2. String token = preferences.getString(\”token\”,null);

更新Text数据

  1. Text text = findComponentById(ResourceTable.Id_text_helloworld);
  2. text.setText(token);

后续操作

获取用户信息请参考QQ开放平台文档 https://wiki.connect.qq.com/get_user_info

文章相关附件可以点击下面的原文链接前往下载

https://harmonyos.51cto.com/resource/1554

原文链接:https://harmonyos.51cto.com

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 HarmonyOS 第三方登录之QQ登录 https://www.kuaiidc.com/89748.html

相关文章

发表评论
暂无评论