因为鸿蒙系统刚出不久,官方的第三方登录 SDK 还没出来,下面就介绍下在鸿蒙应用中实现 QQ 登录的方法(支持唤起 QQ 安卓客户端进行授权)。
前期准备
登录 QQ 开放平台→应用管理→创建应用 ,创建一个网站应用。
https://connect.qq.com/index.html注意:要选择网站应用,移动应用和小程序不适用该方案。
编写代码
①判断是否已登录
获取登录状态:在入口 AbilitySliceMainAbilitySlice 中进行判断。
从数据库获取 token 的值判断是否已经登录账号(已登录返回 token,未登录返回 null)
// 创建数据库(这里使用官方提供的“轻量级数据存储”,相关文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-preference-guidelines-0000000000030083) Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME"); // 从数据库获取token的值判断是否已经登录账号 (已登录返回token,未登录返回null) String token = preferences.getString("token",null);
进行相应跳转:已登录跳转至个人界面 MyAbility,未登录跳转至登录界面 LoginAbility。
if(token != null){ // 已登录,跳转至MyAbility Intent myIntent = new Intent(); myIntent.setParam("token", token); Operation myOperation = new Intent.OperationBuilder() .withBundleName("cn.dsttl3.test") .withAbilityName("cn.dsttl3.qqlogin.MyAbility") .build(); myIntent.setOperation(myOperation); startAbility(myIntent); terminateAbility(); }else { // 未登录,跳转至LoginAbility Intent loginIntent = new Intent(); Operation loginOperation = new Intent.OperationBuilder() .withBundleName("cn.dsttl3.test") .withAbilityName("cn.dsttl3.qqlogin.LoginAbility") .build(); loginIntent.setOperation(loginOperation); startAbility(loginIntent); terminateAbility(); }
②登录界面的操作
申请网络访问权限:在 config.json 添加。
"reqPermissions": [ { "name": "ohos.permission.INTERNET" } ]
登录界面布局文件 ability_login.xml,在布局文件中添加以后 webview 组件。
登录界面的 AbilitySlice LoginAbilitySlice.java,需要用到的几个常量如下:
String state = UUID.randomUUID().toString();// 唯一标识,成功授权后回调时会原样带回。 String client_id = "101***151";//QQ开放平台 应用 APP ID String redirect_uri = "https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin"; //应用 网站回调域 需进行url编码,授权成功后会跳转至该链接 String authorize_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code" + "&client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&state="+ state;
WebView 的配置:
WebView myWebView = (WebView) findComponentById(ResourceTable.Id_WebView_qqlogin); myWebView.getWebConfig().setJavaScriptPermit(true);//支持JavaScript myWebView.getWebConfig().setUserAgent("android");//将UserAgent设置为安卓,授权页才显示QQ客户端一键登录按钮
自定义 WebAgent,当 WebView 即将打开一个链接时调用 isNeedLoadUrl 方法,当在网页上点击“一键登录”时,打开 QQ 客户端。
wtloginmqq 是 QQ 安卓客户端 URL Scheme:
if (request.getRequestUrl().toString().startsWith("wtloginmqq")){ // 打开QQ客户端 Intent qqIntent = new Intent(); Operation qqOperation = new Intent.OperationBuilder() .withAction("android.intent.action.VIEW") .withUri(Uri.parse(request.getRequestUrl().toString())) .build(); qqIntent.setOperation(qqOperation); 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 存储到数据库:
// 将token存入数据库 Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME"); preferences.putString("token",token); preferences.flush();
token 存储完成后跳转至 MyAbility,自定义 WebAgent 完整代码:
myWebView.setWebAgent(new WebAgent(){ // 当WebView即将打开一个链接时调用该方法 @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) { // request.getRequestUrl().toString() WebView即将打开的链接地址 if (request.getRequestUrl().toString().startsWith("wtloginmqq")){ // 打开QQ客户端 Intent qqIntent = new Intent(); Operation qqOperation = new Intent.OperationBuilder() .withAction("android.intent.action.VIEW") .withUri(Uri.parse(request.getRequestUrl().toString())) .build(); qqIntent.setOperation(qqOperation); startAbility(qqIntent); // 向自己的服务器请求token new Thread(new Runnable() { @Override public void run() { while (true){ String getTokenURL = "https://api.dsttl3.cn/Redis/Get?key=" + state; try { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(getTokenURL).build(); String token = client.newCall(request).execute().body().string(); if (token.length() == 32){ getUITaskDispatcher().asyncDispatch(new Runnable() { @Override public void run() { // 将token存入数据库 Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME"); preferences.putString("token",token); preferences.flush(); // 跳转至用户界面 Intent myIntent = new Intent(); Operation myOperation = new Intent.OperationBuilder() .withBundleName("cn.dsttl3.test") .withAbilityName("cn.dsttl3.qqlogin.MyAbility") .build(); myIntent.setOperation(myOperation); startAbility(myIntent); terminateAbility(); } }); break; } Time.sleep(1500); } catch (IOException e) { e.printStackTrace(); } } } }).start(); return false; } return true; } });
加载网页:
myWebView.load(authorize_url);
LoginAbilitySlice.java 完整代码:
import cn.dsttl3.qqlogin.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.aafwk.content.Operation; import ohos.agp.components.webengine.ResourceRequest; import ohos.agp.components.webengine.WebAgent; import ohos.agp.components.webengine.WebView; import ohos.data.DatabaseHelper; import ohos.data.preferences.Preferences; import ohos.miscservices.timeutility.Time; import ohos.utils.net.Uri; import okhttp3.OkHttpClient; import okhttp3.Request; import java.io.IOException; import java.util.UUID; public class LoginAbilitySlice extends AbilitySlice { //QQ开放平台登录授权文档 https://wiki.connect.qq.com/%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c_oauth2-0 String state = UUID.randomUUID().toString();// 唯一标识,成功授权后回调时会原样带回。 String client_id = "101547151";//QQ开放平台 应用 APP ID String redirect_uri = "https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin"; //应用 网站回调域 需进行url编码,授权成功后会跳转至该链接 String authorize_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code" + "&client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&state="+ state; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_login); WebView myWebView = (WebView) findComponentById(ResourceTable.Id_WebView_qqlogin); myWebView.getWebConfig().setJavaScriptPermit(true); myWebView.getWebConfig().setUserAgent("android"); myWebView.setWebAgent(new WebAgent(){ // 当WebView即将打开一个链接时调用该方法 @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) { // request.getRequestUrl().toString() WebView即将打开的链接地址 if (request.getRequestUrl().toString().startsWith("wtloginmqq")){ // 打开QQ客户端 Intent qqIntent = new Intent(); Operation qqOperation = new Intent.OperationBuilder() .withAction("android.intent.action.VIEW") .withUri(Uri.parse(request.getRequestUrl().toString())) .build(); qqIntent.setOperation(qqOperation); startAbility(qqIntent); // 向自己的服务器请求token new Thread(new Runnable() { @Override public void run() { while (true){ String getTokenURL = "https://api.dsttl3.cn/Redis/Get?key=" + state; try { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(getTokenURL).build(); String token = client.newCall(request).execute().body().string(); if (token.length() == 32){ getUITaskDispatcher().asyncDispatch(new Runnable() { @Override public void run() { // 将token存入数据库 Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME"); preferences.putString("token",token); preferences.flush(); // 跳转至用户界面 Intent myIntent = new Intent(); Operation myOperation = new Intent.OperationBuilder() .withBundleName("cn.dsttl3.test") .withAbilityName("cn.dsttl3.qqlogin.MyAbility") .build(); myIntent.setOperation(myOperation); startAbility(myIntent); terminateAbility(); } }); break; } Time.sleep(1500); } catch (IOException e) { e.printStackTrace(); } } } }).start(); return false; } return true; } }); myWebView.load(authorize_url); } }
个人界面,获取 token 信息:
Preferences preferences = new DatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME"); String token = preferences.getString("token",null);
更新 Text 数据:
Text text = findComponentById(ResourceTable.Id_text_helloworld); text.setText(token);
后续操作
获取用户信息请参考 QQ 开放平台文档:
https://wiki.connect.qq.com/get_user_info
附件下载:
https://harmonyos.51cto.com/posts/9448
原文标题:在鸿蒙上实现QQ第三方登录!
文章出处:【微信公众号:HarmonyOS技术社区】欢迎添加关注!文章转载请注明出处。
全部0条评论
快来发表一下你的评论吧 !