Authing 低代码登录组件 Guard Android 版

Authing 的登录组件 Guard 通过低代码方式为应用嵌入多种登录能力与认证方式,几行 JavaScript 代码就可以为你的项目带来强大的认证能力,你可以定制登录体验、配置注册页面以及多因素身份验证,也可以轻松添加各种社会化登录方式实现无缝登录,并且在不同平台拥有一致的登录体验。

Guard 组件正在向 Hyper Component 的方向演进。近期,我们上线了 Guard Android 开源 组件(文末已提供链接),丰富了对主流移动端开发语言的支持,帮助多端应用的开发者极大节约开发成本,降低安全风险

Android Guard 开发者文档:

1、doc/index_zh.md · Authing/android_guard - Gitee.com

Android Guard 是开源的,源码地址:

2、Authing/android_guard

基于语义化思想的全新编程模型

人类社会的进步本质上是生产力的提升。生产力提升后,生产关系也随之变化,从而进一步提高生产力。编程语言是一种生产力工具,我们一直都在想方设法提高编程效率。编程语言本身也一种语义化,计算机只认识高电压和低电压,它们甚至对 0 和 1 都一无所知。当人类发明 0 和 1 的时候,就迈出了语义化的第一步。对人类来说,数字也是描述物理世界的一种语义。

Guard 就是在数字世界语义化的一次呈现。

从功能上看,Guard 可根据你的需求进行配置,建议用于单页面应用程序它可以轻松添加各种社会化登录方式,使你的用户无缝登录,并且在不同平台拥有一致的登录体验。Guard 为开发者屏蔽了很多底层认证的实现细节,同时也包括繁琐的 UI 开发

优势 1:声明式编程

首先看 wiki 对声明式编程的解释。如 wiki 所说,声明式编程适合于解决领域相对确定的问题,这些问题不需要图灵完整。整个开发过程就是逐渐减少逻辑空间可能性,最终完成特定业务需求。领域特有语言 DSL(Domain-Specific Language)是非常好的声明式编程例子。

一般编程模式叫做**命令式编程,**Guard 支持这种模式。在这种模式下,开发人员对所有逻辑有绝对的控制权,但这也意味着需要写更多无价值的、冗余的代码。写它们的唯一原因是 Android 是个通用平台,它不知道认证的领域模型。

如果你的认证流程是比较标准的,建议使用我们提供的声明式编程模型,会极大提高开发效率。

如果应用能接受 Authing 风格界面,在需要启动认证流程的控制器(如闪屏)上,调用:

AuthFlow.start(this); // 'this' is current activity

然后通过 onActivityResult 拿到认证数据:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == RC_LOGIN && resultCode == OK && data != null) {
        Intent intent = new Intent(this, MainActivity.class);
        UserInfo userInfo = (UserInfo) data.getSerializableExtra("user");
        intent.putExtra("user", userInfo);
        startActivity(intent);
    }
}

然而在移动端,几乎每个 App 的界面都是定制化的,认证流程也稍有不同。首先,需要用我们提供的 Hyper Component 定义好界面。这一步是必不可少的,虽然业界有 pix2code 这样的工具尝试从原型直接生成代码,但目前看起来还没有达到生产环境标准。

有了界面后,接下来只需要声明流程即可。

// replace layouts with your customized layouts
AuthFlow.start(this, R.layout.activity_login_authing)
        .setRegisterLayoutId(R.layout.activity_register_authing)
        .setForgotPasswordLayoutId(R.layout.activity_authing_forgot_password)
        .setResetPasswordByEmailLayoutId(R.layout.activity_authing_reset_password_by_email)
        .setResetPasswordByPhoneLayoutId(R.layout.activity_authing_reset_password_by_phone);

这就是业务开发人员需要写的全部代码。

优势 2:数据实时同步

很多 App 和网页的登录界面是分为两个页面完成的。在第一个页面,用户只需要输入用户名或者电话号码。第二个页面,用户需要输入密码或者验证码。

这样设计的好处是用户只需要专注一件事情,避免信息输入错误,如果错了,只需要改其中一个信息,不用重复输入。

注册,则需要很多页面完成。对于开发人员来说,这样分页的设计需要通过某种机制将前一个页面中的控件数据带给下一个页面。在 Android 里面,我们可以通过在 Intent 的 Bundle 中填充数据,然后在下一个页面去获取 Intent 里面的 Bundle。

在语义化编程思想下,我们的 Hyper-Component 如何自动感知数据变化?

第一个想法是把控件数据放到一个全局的 Map 里,Key 就是某个控件类型,Value 就是这个控件对应的数据。

这样的设计有以下几个问题:

  • 会导致内存泄漏(虽然内存不会一直增长,但存储的数据空间是无法被回收的)

  • 数据只有全局作用域

  • 无法表示数据的流动方向

我们以重置密码来举例:
image

image

在第一个页面用户输入了邮箱,到了第二个页面,输入框能显示第一个页面的邮箱,假设用户又手动修改了邮箱,点击 Back 按钮回到第一个页面,这时应该保持第一个页面的邮箱数据不跟随第二个变化。

控件数据的处理有几个特征:

特征1:作用域跟随控制器 。在控制器还存在的情况下,即使控件对用户不可见,那也应该保留自己的数据。

特征2:数据的流向规则应该是——如果用户进行了某种确认操作,如点击了「下一步」、「登录」、「注册」 等表示确认的按钮,则应该把控件的数据取出,复制一份传给下一个页面,或者传给逻辑控制器,比如网络请求;但如果用户进行了某种取消操作,如点击了 Back 按钮,点击了页面上的“取消”按钮,则应该丢弃当前控件的数据,因为从用户角度看,这些是脏数据,所以用户才取消了操作。

特征3:在给定业务场景下,Hyper-Component 的数据是按类型存储,而不是按实例存储 。也就是说,如果在整个认证流程中,出现了多个电话号码输入框**( PhoneNumberEditText),那么所有实例的数据都是一致的,更新其中一个(如果用户进行了确认操作),则所有其他实例的数据也实时同步刷新。这和通用的面向对象编程思想是不同的。

如果需要不同实例控件的数据不一致,应该再开发新的 Hyper-Component。

比如,用作登录的**电话号码输入框和用作紧急联系人的电话号码输入框其实是两个控件类型,因为其语义是不同的

根据以上思考,我们 Hyper-Component 的数据能在整个认证流程中实时的、正确的流转。当控制器销毁时,数据随之销毁,省掉了开发人员需要手动处理数据的繁琐工作。

优势 3:可交互

我们将语义化后的组件称为 Hyper-Component。我们通过一个典型的认证流程来说明(以 Android 为例,其他平台类似)。

步骤 1:登录
image

步骤 2:注册

image

步骤 3:密码重置

image
image

这里的 “可交互” 包括:

  1. 内容可以动态改变,如顶部的 Logo,算是一个可交互控件,需要被语义化。如
  2. 用户可以操作,如按钮。虽然按钮的文字、背景都是固定的,但用户可以点击,所以它也算是可交互控件。

上面例子中的登录界面,包括“忘记密码”,“立即注册”这样的小按钮也需要被语义化为:,

你可在此链接查看布局示意:

guard/src/main/res/layout/authing_login.xml · Authing/android_guard - Gitee.com

优势 4:扩展性

如果我们提供的 Hyper-Component 不能完全满足业务需求,开发人员可以很方便进行扩展。参考文末链接中任意 Hyper-Component 的原生实现,编写扩展控件原生代码,在布局文件里使用。

Android Guard 视频教程

Guard 采用了全新的语义化编程模型 (opens new window),可以快速构建自定义风格的认证流程。相对于手动实现,开发效率 x10。

代码示例

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Authing.init(getApplicationContext(), "your_app_id");
        AuthFlow.start(this);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == AuthActivity.RC_LOGIN && resultCode == AuthActivity.OK) {
            UserInfo userInfo = (UserInfo) data.getSerializableExtra("user");
            Log.d("Guard", userInfo.getUsername());
        }
    }
}

还有很酷的事,我们将推出 Authing 低代码平台、Authing Web IDE 以及移动端低代码引擎,从而实现认证流程及界面的 0 代码开发,让每一个工程师的生产力得到解放! 对于开发者 ,每天都面临开发或者运维各式各样的应用登录界面,那你认为什么样的登录框可以称之为优秀呢? :point_right: 立即参与 Authing 推荐优秀登录页活动赢虎年咆哮礼吧~