Android原生同步登录状态到H5网页避免二次登录

本文介绍了如何在Android原生应用内嵌WebView时,同步登录状态到H5页面,避免用户二次登录。主要方法是通过SharedPreferences保存登录后的UserInfo,并将其转化为cookie,通过WebView传递给H5页面。在H5端,利用cookie获取登录信息,实现状态同步。提供了详细的Android和Vue实现代码示例。
摘要由CSDN通过智能技术生成

本文解决的问题是目前流行的 Android/IOS 原生应用内嵌 WebView 网页时,原生与H5页面登录状态的同步。

大多数混合开发应用的登录都是在原生页面中,这就牵扯到一个问题,如何把登录状态传给H5页面呢?总不能打开网页时再从网页中登录一次系统吧… 两边登录状态的同步是必须的。

100 多位经验丰富的开发者参与,在 Github 上获得了近 1000star 的全栈全平台开源项目想了解或参与吗?
项目地址:https://github.com/cachecats/coderiver

一、同步原理

其实同步登录状态就是把登录后服务器返回的 tokenuserId 等登录信息传给H5网页,在发送请求时将必要的校验信息带上。只不过纯H5开发是自己有一个登录页,登录之后保存在 Cookie 或其他地方;混合开发中H5网页自己不维护登录页,而是由原生维护,打开 webview 时将登录信息传给网页。

实现的方法有很多,可以用原生与 JS 的通信机制把登录信息发送给H5,关于原生与 JS 双向通信,我之前写了一篇详解文章,不熟悉的同学可以看看:

Android webview 与 js(Vue) 交互

这里我们用另一种更简单的方法,通过安卓的 CookieManagercookie 直接写入 webview 中。

二、安卓端代码

这是安卓开发需要做的。

先说一下步骤:

  1. 准备一个对象 UserInfo ,用来接收服务端返回的数据。
  2. 登录成功后把 UserInfo 格式化为 json 字符串存入 SharedPreferences 中。
  3. 打开 webview 时从 SharedPreferences 取出上一步保存的 UserInfo
  4. 新建一个 MapUserInfo 以键值对的格式保存起来,便于下一步保存为 cookie。
  5. UserInfo 中的信息通过 CookieManager 保存到 cookie 中。

看似步骤很多,其实就是得到服务端返回的数据,再通过 CookieManager 保存到 cookie 中这么简单,只不过中间需要做几次数据转换。

我们按照上面的步骤一步步看代码。UserInfo 对象就不贴了,都是些基本的信息。

将 UserInfo 保存到 SharedPreferences

登录接口请求成功后,会拿到 UserInfo 对象。在成功回调里通过下面一行代码保存 UserInfoSharedPreferences

//将UserData存储到SP
SPUtils.putUserData(context, result.getData());

SPUtils 是操作 SharedPreferences 的工具类,代码如下。

包含了保存和取出 UserInfo 的方法(代码中对象名是 UserData),保存时通过 Gson 将对象格式化为 json 字符串,取出时通过 Gson 将 json 字符串格式化为对象。

public class SPUtils {
   
    /**
     * 保存在手机里面的文件名
     */
    public static final String FILE_NAME = "share_data";
    
    /**
     * 存储用户信息
     *
     * @param context
     * @param userData
     */
    public static void putUserData(Context context, UserData userData) {
   
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        Gson gson = new Gson();
        String json = gson.toJson(userData, UserData.class);
        editor.putString(SPConstants.USER_DATA, json);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 获取用户数据
     *
     * @param context
     * @return
     */
    public static UserData getUserData(Context context) {
   
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        String json = sp.getString(SPConstants.USER_DATA, "");
        Gson gson = new Gson();
        UserData userData = gson.fromJson(json, UserData.class);
        return userData;
    }
}

取出 UserInfo 并保存到 cookie 中

这里封装了一个带进度条的 ProgressWebviewActivity ,调用时直接打开这个 Activity 并将网页的 url 地址传入即可。在 Activity 的 onResume 生命周期方法中执行同步 cookie 的逻辑。为什么在 onResume 中执行?防止App 从后台切到前台 webview 重新加载没有拿到 cookie,可能放在 onCreate 大多数情况下也没有问题,但放到 onResume 最保险。

@Override
protected void onResume() {
   
    super.onResume();
    Logger.d("onResume " + url);
    //同步 cookie 到 webview
    syncCookie(url);
    webSettings.setJavaScriptEnabled(true);
}

/**
 * 同步 webview 的Cookie
 */
private void syncCookie(String url) {
   
    boolean b = CookieUtils.syncCookie(url);
    Logger.d("设置 cookie 结果: " + b);
}

同步操作封装到了 CookieUtils 工具类中,下面是 CookieUtils 的代码:

这个工具类中一共干了三件事,从 SharedPreferences 中取出 UserInfo,将 UserInfo 封装到 Map 中,遍历 Map 依次存入 cookie。

public class CookieUtils {
   

    /**
     * 将cookie同步到WebView
     *
     * @param url WebView要加载的url
     * @return true 同步cookie成功,false同步cookie失败
     * @Author JPH
     */
    public static boolean syncCookie(String url) {
   
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
   
            CookieSyncManager.createInstance(MyApplication.getAppContext());
        }
        CookieManager cookieManager = CookieManager.getInstance();

        Map<String, String> cookieMap = getCookieMap()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值