Skip to content

ZhongceXie/react-native-ali-one-pass

 
 

Repository files navigation

react-native-ali-onepass

此项目由react-native-ali-onepass fork 而来

Expo 说明

需要用到expo development build 然后再找到ios 和安卓的文件夹,执行下方安装步骤 (https://docs.expo.dev/guides/local-app-development/)

安装

$ npm install react-native-ali-one-pass-login --save

$ yarn add react-native-ali-one-pass-login

对于android端需在在 android/app/build.gradle中添加下面的代码

android {
  repositories {
      flatDir {
          dirs 'libs', '../../node_modules/react-native-ali-one-pass-login/android/libs'
      }
  }
}

对于ios还需要运行以下命令 $ cd ios && pod install

api说明

详细内容请看api详细说明

用法

使用示例:封装成hook使用

import {useFocusEffect} from '@react-navigation/native';
import {useCallback} from 'react';
import {useRef} from 'react';
import {Platform} from 'react-native';
import * as onePassSDK from 'react-native-ali-one-pass-login';
import {useDispatch} from 'react-redux';
import {ONEPASS_ANDROID_KEY, ONEPASS_IOS_KEY} from "@/constants/OnePass";

export async function setUIConfig() {
    const operatorType = await onePassSDK.getOperatorType();
    return onePassSDK.setUIConfig({
        //状态栏
        lightColor: true,
        statusBarHidden: true,
        // 弹窗使用
        dialogHeightDelta: 100,
        alertBarHidden: true,
        // alertBarCloseImgPath: 'onepass_close_btn',
        alertBarCloseImgWidth: 30,
        alertBarCloseImgHeight: 30,
        // 标题栏
        navColor: '#FFFFFF',
        navTextColor: '#333333',
        navText: '',
        navTextSize: 18,
        webNavColor: '#FFFFFF',
        webNavTextColor: '#333333',
        webNavTextSize: 18,
        navReturnImgPath: 'back_icon',
        navHidden: true,
        // logo
        logoImgPath: 'ic_launcher_round',
        logoHidden: false,
        logoWidth: 80,
        logoHeight: 80,
        // logoOffsetY: getOffsetY(175),
        // 手机号掩码
        numberColor: Platform.OS === 'android' ? '#f5f5f5' : '#333333',
        numberSize: 25,
        // slogan
        sloganText: `${operatorType}提供认证服务`,
        sloganTextColor: '#B2B2B2',
        sloganTextSize: 13,
        // sloganOffsetY: getOffsetY(384),
        // 登录按钮
        logBtnText: '本机号码一键登录',
        logBtnTextColor: '#f5f5f5',
        logBtnTextSize: 18,
        // ios
        // logBtnBackgroundPaths: ['loginbg', 'loginbg', 'loginbg'],
        // android
        // logBtnBackgroundPath: 'loginbg',
        logBtnMarginLeftAndRight: 35,
        // 其他登录方式
        switchAccText: '其他登录方式',
        switchAccTextSize: 15,
        switchAccTextColor: '#0EA8FF',
        // 协议栏
        privacyBefore: '登录即同意',
        privacyEnd: '并授权获取本机号码',
        checkboxHidden: true,
        privacyState: true,
        appPrivacyOneName: '协议',
        appPrivacyOneUrl: 'https://www.baidu.com',
        vendorPrivacyPrefix: '《',
        vendorPrivacySuffix: '》',
        privacyTextSize: 12,
        appPrivacyBaseColor: '#B2B2B2',
        appPrivacyColor: '#0EA8FF',
        pageBackgroundPath: 'loginbg',
    });
}


/**
 * 手机号一键登录hook
 */
const usePhoneLogin = () => {
    const dispatch = useDispatch();

    // 是否允许一键登录
    const onePassEnable = useRef(false);
    // 一键登录API初始化状态
    const onePassSDKIniting = useRef(true);
    // 延迟执行函数队列
    const delayFuncQueue = useRef<Function[]>([]);

    // 调用延迟函数执行队列
    const callDelayFuncQueue = useCallback(() => {
        // 执行初始化前调用的函数
        // 为了防止延迟执行的函数与初始化状态海边函数同时执行,推迟函数队列的执行时间
        setTimeout(() => {
            delayFuncQueue.current.forEach(func => {
                func();
            });
            delayFuncQueue.current = [];
        }, 100);
    }, []);

    useFocusEffect(
        useCallback(() => {
            // 初始化
            onePassSDK
                .init(Platform.OS === 'android' ? ONEPASS_ANDROID_KEY : ONEPASS_IOS_KEY)
                .then(async () => {
                    // 检测一键登录是否可用
                    onePassSDK
                        .checkEnvAvailable(2)
                        .then(async () => {
                            // 预获取手机号
                            onePassSDK
                                .prefetch()
                                .then(() => {
                                    onePassEnable.current = true;
                                })
                                .catch(res => {
                                    console.log(res.code, 'presetch');
                                })
                                .finally(() => {
                                    // 设置SDK加载状态
                                    onePassSDKIniting.current = false;
                                    callDelayFuncQueue();
                                });
                        })
                        .catch(res => {
                            // 设置SDK加载状态
                            onePassSDKIniting.current = false;
                            callDelayFuncQueue();
                        });
                })
                .catch(res => {
                    // 设置SDK加载状态
                    onePassSDKIniting.current = false;
                    callDelayFuncQueue();
                });
            const succListener = onePassSDK.addListener(
                onePassSDK.EVENTS.onTokenSuccess,
                (data: any) => {
                    // 运营商Token获取成功
                    if (data.code === onePassSDK.RESULT_CODES.TOKENSUCCESS) {
                        // 获取token成功,将token传递后端校验
                        console.log(data.token);
                    } else {
                        if (
                            ![onePassSDK.RESULT_CODES.AUTHPAGESUCCESS, '700004'].includes(
                                data.code,
                            )
                        ) {
                            onePassSDK.hideLoginLoading();
                            onePassSDK.quitLoginPage();
                            console.log('popuplogin');
                        }
                    }
                },
            );
            const failListener = onePassSDK.addListener(
                onePassSDK.EVENTS.onTokenFailed,
                (data: {code: string; msg: string}) => {
                    console.log(data.code, onePassSDK.RESULT_CODES.SWITCHAUTHWAY);
                    if (data.code === onePassSDK.RESULT_CODES.SWITCHAUTHWAY) {
                        if (Platform.OS === 'android') {
                            console.log('正在切换登录方式','android跳转');
                        } else {
                            console.log('正在切换登录方式','ios跳转');
                        }
                        setTimeout(() => {
                            onePassSDK.quitLoginPage();
                        }, 300);
                    }
                    console.log(data, 'fail data 一键登录失败');
                    onePassSDK.hideLoginLoading();
                },
            );
            return () => {
                succListener.remove();
                failListener.remove();
            };
        }, [callDelayFuncQueue, dispatch]),
    );

    const goLogin = useCallback(async () => {
        // 当前手机不支持一键登录,跳转去普通登录页面
        if (!onePassEnable.current) {
            throw "unsupported"
        }
        // 等待设置一键登录UI页面完成
        await setUIConfig();
        // 拉起一键登录页面
        onePassSDK
            .onePass()
            .then(res => {})
            .catch(e => {
                console.log(e);
            });
    }, []);

    return useCallback(async () => {
        // SDK初始化成功后再调用去登录页面的函数

        if (onePassSDKIniting.current) {
            delayFuncQueue.current.push(goLogin);
            return;
        }
       return goLogin();
    }, [goLogin]);
};

export default usePhoneLogin;

使用

import {Text} from 'react-native';
import { View } from '@ant-design/react-native'

import { StyleSheet } from 'react-native';
import {Button, Flex, WingBlank} from "@ant-design/react-native";
import {useSelector} from "react-redux";
import {router} from "expo-router";
import {useEffect, useState} from "react";
import usePhoneLogin from "@/hooks/usePhoneLogin";


export default function User() {
    const isLoggedIn = useSelector((state:any) => state.auth.isLoggedIn)
    const onPhoneLogin = usePhoneLogin();

    const onePassLogin =() => {
        onPhoneLogin()
            .then(() =>{
                console.log("success")
            }).catch(e => {
                console.log("error: " + e)
            router.push('..//auth')
        })
    }
    return (
      <View style={styles.centered}>
          {isLoggedIn ? <Text>Welcome</Text> :
              // <Button onPress={() => isOnepassAvailable ? onePass(): router.push('..//auth')}>Login</Button>
              <Button onPress={() => onePassLogin()}>Login</Button>
          }
      </View>
  );
}


const styles = StyleSheet.create({
  centered: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Objective-C 72.9%
  • Java 17.7%
  • JavaScript 6.0%
  • Shell 2.0%
  • Other 1.4%