如何使用 FaceIO 开发基于 AI 的 Web App 用户认证模块

在以往的Web应用信息系统开发中,用户认证是不可或缺的功能模块。用户认证功能包括用户注册和登录认证。在以往的开发方法中,实现用户认证功能模块的常用方式是使用邮件和短信进行验证。现在,许多用户的电脑都配备了摄像头,可以充分利用人脸识别的人工智能技术来实现用户认证。我使用 FaceIO 的 JavaScript 库在 Web 应用项目中实现用户身份验证。

本文主要介绍如何通过第三方AI服务接口开发Web应用项目的用户登录模块。Web 应用程序项目的源代码已上传到 GitHub,并且基于 MIT 协议。没有任何限制。
这个项目是一个简单而完整的Web微服务系统。项目采用前后端分离的开发方式,使用不同的项目文件路径。前端使用 React,后端使用 Java 1.8 和带有 Spring Boot 的微服务,数据库使用 MySQL。前端在React中集成FaceIO,实现AI的对接。

Technology stack of WEB APP project
Operating System:Windows 10
Front-end: Node.js 18.0.0, React 18.2.0, FaceIO, CoreUI 4.3.1
Front-end development tool: WebStorm 2019
Back-end: Java 1.8, Spring Boot, JWT, Mybatis, Maven
Back-end development tool: IntelliJ IDEA 2019
Database: MySQL 5.7+

该 Web 项目的源代码包括前端、后端和数据库,是一个完整的 Web 应用程序信息系统。前端开发使用React,后端开发使用Java和SpringBoot,数据库使用MySQL。第三方AI服务接口使用FaceIO。FaceIO 提供了一个在线 JavaScript 库,可以在前端代码中直接引用。在前端引用 FaceIO 库后,添加少量代码即可轻松实现人脸认证,与后端集成后即可实现完整的用户认证。前端 UI 使用 CoreUI 的免费模板。

FaceIO的使用不仅限于浏览器。它可以在任何浏览器上运行,包括 IE、Chrome、Firefox 和 Safari。而且,所有的AI业务处理都是在FaceIO的服务器上完成的,所以FaceIO需要有用户当前浏览器上的摄像头访问权限。

如何在前端 React 框架中使用 FaceIO 库
步骤 1:安装和配置 Node.js 环境
从Node.js官网下载对应版本Node.js的压缩包。我使用的版本是 V18.0.0。如果你想运行我在本地发布的开源 Web 项目,你最好也使用 V18.0.0。由于Node.js版本的迭代速度相对较快,如果使用其他版本,则此开源 Web 项目中使用的本地 JavaScript 库可能不兼容,可能无法运行。

下载Node.js的压缩包后,解压到英文目录下。因为我使用 IntelliJ IDEA 开发前端 React,所以我需要在 IntelliJ IDEA 中配置 Node.js 和 NPM,并指定 Node.js 的安装目录。

在 IntelliJ IDEA 中配置 Node.js 和 NPM 后,可以通过 IntelliJ IDEA 工具创建一个 React App 项目。

第 2 步:在 FaceIO 中申请公共 ID
FaceIO 提供了一个在线 JavaScript 库。如果你想使用FaceIO提供的AI服务,你需要先为你的APP申请一个公共ID。登录,先注册账号,然后根据项目创建应用获取公共 ID。这个公共 ID 需要写在你的 React App 项目的代码中。申请公共 ID 时,FaceIO 会为您的应用提供免费版本的公共 ID,但对使用次数有限制。

第 3 步:在 React App 项目中使用 FaceIO
外部 JavaScript 库地址由 FaceIO 提供。

在 React App 项目的代码中,可以这样引用。例如,在我的 WEB 项目文件中Login.js:

  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.src = 'https://cdn.faceio.net/fio.js';
  document.head.appendChild(script);

引入 fio.js 后,定义常量就可以使用了。代码如下所示:

  let myFaceIO;
  useEffect(()=>{
    //eslint-disable-next-line
    myFaceIO = new faceIO("fioab497");
  },[])

fioab497是注册后我的应用的公共 ID。您需要替换应用的公共 ID。

请注意,在上面代码 React 的 hook 函数中,有一行代码。如果您在开发环境中安装了 eslint 插件,则需要添加以下代码行。如果没有这行代码,eslint 检测会认为存在错误。错误提示如下:useEffect()//eslint-disable-next-line

ERROR in [eslint]
src\views\pages\login\Login.js
  Line 52:20:  'faceIO' is not defined  no-undef

在开发环境中,Web 项目将无法运行。因此,您需要添加这一行注释代码,让 eslint 跳过下一行代码的检测。

FaceIO提供人脸注册功能。代码是这样使用的:enroll()

  const faceSignUp = async ()=>{
    myFaceIO.enroll({
      "locale": "auto"
    }).then(userInfo => {
      console.log("facialId: " + userInfo.facialId)
      console.log(userInfo);
      handleLogin(userInfo,"login/signUp");
    }).catch(errCode => {
      console.log(errCode);
    })
  }

在上面的代码中,该函数以 JSON 字符串格式输入数据,并将其传递给 FaceIO 的人工智能接口。UserInfo 是 FaceIO 进行人脸验证后返回的数据对象。 是一个用户自定义的函数,用于在收到 FaceIO 返回的数据对象后与我的后端进行通信。当然,你也可以根据自己的开发情况,设置其他自定义函数来处理 FaceIO 返回的数据对象。enroll()handleLogin ()

在函数输入的JSON字符串格式数据中,还可以添加自定义JSON字符串数据。代码如下所示:enroll()

  const faceSignUp = async ()=>{
    myFaceIO.enroll({
      "locale": "auto", // Default user locale
      "payload": {
        "user": 123456, 
        "email": "name@example.com"
        }
    }).then(userInfo => {
      console.log("facialId: " + userInfo.facialId)
      console.log(userInfo);
      handleLogin(userInfo,"login/signUp");
    }).catch(errCode => {
      console.log(errCode);
    })
  }

payload是 FaceIO 可以返回的数据节点。在“payload”中,您可以添加返回所需的JSON格式数据,并根据自己的开发需求自定义数据内容。

调用函数后,浏览器会显示FaceIO提供的用于人机交互的UI,并在浏览器提示符下启动摄像头。您需要单击“是”。FaceIO提供的UI界面会自动确认用户在当前摄像头前的脸部两次,并要求当前用户确认PIN码的设置两次。输入的 PIN 码将用于人脸身份验证。enroll()

FaceIO 提供人脸认证函数 authenticate()。代码是这样使用的:

  const faceSignIn = async ()=>{
    myFaceIO.authenticate({
      "locale": "auto"
    }).then(userInfo => {
      console.log("facialId: " + userInfo.facialId)
      console.log(userInfo);
      handleLogin(userInfo,"login/signIn");
    }).catch(errCode => {
      console.log(errCode);
    })
  }

调用函数后,浏览器会显示FaceIO提供的用于人机交互的UI界面,启动摄像头,并要求当前登录用户输入人脸注册时设置的PIN码。authenticate()

我的自定义函数会根据 FaceIO 返回的数据传递到后端。后端接收数据,分析数据,并将结果返回给前端。前端执行后续的业务逻辑。如果用户认证成功,后端会将 Token 数据返回给前端。前端确认登录成功后,页面会跳转到 Dashboard,完成整个用户认证过程。handleLogin ()

前端收到令牌数据后,将令牌数据保存在用户当前浏览器的会话存储中。我在会话存储中自定义了一个名为“Authorization”的项目来存储令牌数据。保存 Token 数据的函数代码如下:

const setAuthorization = (Auth) => {
    sessionStorage.setItem('Authorization',Auth)
}

获取 Token 数据的函数代码如下:

function getAuthorization () {
    let Author = sessionStorage.getItem('Authorization')
    if (Author === null) return ''
    return Author
}

我已经设置了在系统中自动加载 Token 数据。在后续的业务处理中,在访问后端 API 时,Token 数据会自动放置在请求头的授权中。代码如下所示:

instanceForm.interceptors.request.use(
    (config) => {
        config.headers.authorization = getAuthorization()
        return config
    }
)

我的项目的前端源代码可以从 GitHub 下载。

如何在后端完成用户身份验证
在 Web 项目中,我使用 SpringBoot 作为后端,开发语言是 Java 1.8。在 Spring 框架中,创建一个处理用户登录身份验证的控制层类。此 LoginController 类也是用于处理用户登录身份验证的 API 接口。代码如下:

package com.auto17.base.controller;
import ...
import ...
@RestController
@RequestMapping("/login")
@CrossOrigin
public class LoginController{
    protected final Logger logger = LoggerFactory.getLogger(LoginController.class);
    @Autowired
    private IAppUserService appUserService;
    @PostMapping("/signUp")
public AjaxResult signUp(@RequestBody JSONObject userInfo) {
   ...
    }
    @PostMapping("/signIn")
public AjaxResult signIn(@RequestBody JSONObject userInfo) {
   ...
    }
}

在上面的代码中,表示整个 LoginController 类的 API 路径,
表示用户注册的 API 路径,接收 POST 数据请求,函数用于处理用户注册。完整的 API 路径是 。
表示用户身份验证的 API 路径。它接收 POST 数据请求。该函数用于处理用户身份验证。完整的 API 路径是 。@RequestMapping (“/login”)@PostMapping (“/signUp”) signUp()/login/signUp@PostMapping (“/signIn”)signIn()/login/signIn

在函数 or 中,解析前端 React 传递的 JSON 格式数据。从 JSON 数据中提取 node 的值。 是 FaceIO 返回的唯一标识符,用于成功进行用户身份验证。此 ID 是唯一的。在这个 Web 项目中,我通过“facialId”来判断用户,并通过 来识别用户。signUp()signIn()facialIdFacialIdfacialId

需要注意的是,在这个 Web 项目中,JSON 格式的数据以明文形式从前端传输到后端,无需数据加密。如果您正在使用它,您可以添加安全函数以JSON格式加密数据。前端加密后,消息从前端传输到后端。后端解密后,解析JSON格式数据。有许多加密方法。我推荐 RSA 算法。RSA算法是一种非对称的加解密算法。在后端,即用户访问网页时,在服务器端生成一对RSA密钥,包括公钥和私钥,并将公钥提供给前端。前端使用公钥对JSON格式的数据进行加密,然后将其传输到后端。后端根据私钥对其进行解密。解密后,解析JSON格式数据。这样可以最大限度地保护“facialId”的值不被轻易拦截。

在后端,用户被 成功识别后。我使用 JWT 方法保存当前登录用户的信息。类 JWTUtils 中的函数 getToken(AppUser 用户)获取当前用户的令牌。我使用 的值作为签名密钥。代码如下所示:facialId facialId

public class JWTUtils {
    public static String getToken(AppUser user) {
        Calendar instance = Calendar.getInstance();
        //Token expiration time
        instance.add(Calendar.DATE, 1);
        JWTCreator.Builder builder = JWT.create();
        return builder.withAudience(String.valueOf(user.getUserId()))
                .withClaim("userId", user.getUserId())
                .withClaim("facialId", user.getFacialId())
                .withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(user.getFacialId()));
    }
}

获取当前登录用户的 Token 后,后端会将 Token 数据返回给前端。

用户认证成功后,后端会在后续的每次 API 请求中收到用于用户认证的 Token 数据。我创建了一个拦截器类 JWTInterceptor,用于在每次 API 请求之前验证 Token 数据。代码如下所示

package com.auto17.base.security;
import com.auto17.base.domain.AjaxResult;
import com.auto17.faceLogin.domain.AppUser;
import com.auto17.faceLogin.service.IAppUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class JWTInterceptor extends HandlerInterceptorAdapter {
    protected final Logger log = LoggerFactory.getLogger(JWTInterceptor.class);
    @Autowired
    private IAppUserService appUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("authorization");
        log.info("token="+token);
        if(StringUtils.isEmpty(token)){
            log.error("authorization is Empty");
            errorOut(response,"authorization is Empty");
            return false;
        }
        try {
            //get login user info
            String userNoString=JWTUtils.getAudience(token);
            log.info("userNoString="+userNoString);
            AppUser loginUser=appUserService.selectAppUserById(Long.valueOf(userNoString));
            if(loginUser!=null){
                JWTUtils.verify(token,loginUser.getFacialId());
                request.setAttribute("loginUser", loginUser);
            }else{
                errorOut(response,"check user fail");
            }
        } catch (Exception e) {
            errorOut(response,"check verify fail");
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private void errorOut(HttpServletResponse response,String msg){
        try {
            response.setHeader("Access-Control-Allow-Origin","*");
            response.setContentType("text/json; charset=utf-8");
            response.setHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS,DELETE");
            response.setHeader("Access-Control-Max-Age","3600");
            response.addHeader("Access-Control-Allow-Headers", "*");
            PrintWriter writer=response.getWriter();
            writer.print(AjaxResult.error(msg));
            writer.flush();
            writer.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

我的项目的后端(服务器)源代码可以从 GitHub 下载。

除了在前端提供易用性外,FaceIO 还提供 REST API,允许您从后端管理应用程序。每个 FACEIO 应用程序都会自动分配一个 API 密钥。您可以从 FaceIO 控制台上的应用程序管理器中检索此密钥。API 密钥允许您以编程方式从专用后端环境管理应用程序。我们可以使用 SpringBoot 的 RestTemplate 轻松实现它。因为我的项目是一个简单的应用程序,所以我没有在这方面使用它。如果您有兴趣,可以访问 FaceIO 的 rest API 的在线文档。

如何设计数据库
在我的 Web 项目中,数据库使用 MySQL。为了配合人脸识别,设计了一个简单的用户表。创建表 SQL 语句:

CREATE TABLE `app_user`  (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `facial_id` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `nick_name` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `true_name` varchar(160) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `age` smallint(6) DEFAULT NULL,
  `gender` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `reg_time` datetime(0) DEFAULT NULL,
  `last_login_time` datetime(0) DEFAULT NULL,
  PRIMARY KEY (`user_id`) USING BTREE,
  UNIQUE INDEX `idx_facialid`(`facial_id`) USING BTREE
)

数据表中的字段用于存储 FaceIO 返回的唯一用户 ID。这是一个简单的用户数据表。没有用户密码字段或用户移动电话字段。此用户数据表仅使用“facial_id”字段完成登录用户认证和识别。facial_id

我的项目的数据库创建SQL脚本可以从GitHub下载。

用户从 FaceIO 完成注册后,FaceIO 返回的 JSON 字符串数据包含“details”节点,即 FaceIO 人工智能识别的当前用户的年龄和性别。我将其存储在用户数据表的“年龄”和“性别”字段中。

这是我目前的开发方法。当然,您也可以保留之前的用户认证开发方法,仍然保留登录密码和短信认证。在原有开发方式的基础上,新增了 FaceIO 的人脸认证方式。在您的原始用户数据表中,添加绑定人工智能人脸识别的字段。facial_id

  • 36
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 作为AI语言模型,我无法给出准确的建议,但是一般来说,你可以选择以下几种后端开发方式: 1. 使用Node.js开发后端 Node.js是一种非常流行的JavaScript运行时环境,具有高效的I/O操作和可扩展性。你可以使用Node.js框架,如Express、Koa等,来开发RESTful API接口,用于前端与后端之间的数据交互。 2. 使用Java开发后端 Java是一种广泛使用的编程语言,具有广泛的应用场景。你可以使用Java的Web框架,如Spring、Spring Boot等,来开发RESTful API接口,用于前端与后端之间的数据交互。 3. 使用PHP开发后端 PHP是一种常用的服务器端脚本语言,适用于快速开发Web应用程序。你可以使用PHP框架,如Laravel、CodeIgniter等,来开发RESTful API接口,用于前端与后端之间的数据交互。 以上仅是一些常见的后端开发方式,具体选择要根据你个人的喜好和实际情况来定。同时,需要注意的是,无论使用什么技术栈开发后端,都需要注意数据安全和性能优化等问题。 ### 回答2: 使用uni-app开发在线买菜app的后端可以选择多种技术进行开发。以下是一些常见的选择: 1. Node.js + Express:Node.js是一个基于JavaScript运行的服务器端开发环境,擅长处理并发请求。搭配Express框架,可以快速搭建可靠的后端服务器。Node.js具有非阻塞I/O的特点,适合处理高并发请求、实时通信等场景。 2. Python + Django:Python是一种简单易学的编程语言,擅长处理各种复杂的数据操作和算法。配合Django框架,可以快速构建高效、稳定的后端系统。Django提供了丰富的功能和工具,可以简化开发过程,并提供了灵活的数据库操作和认证授权功能。 3. Java + Spring Boot:Java是一种跨平台的编程语言,具有广泛的应用领域。Spring Boot是一个Java开发框架,简化了Java应用的开发和配置。使用Spring Boot可以快速构建可扩展、可维护的后端系统,提供了各种丰富的功能和工具。 无论选择哪种后端开发技术,重要的是确保后端系统的稳定性、安全性和性能。同时,需要合理设计数据库结构,实现数据的存储和访问,并提供良好的API接口供前端调用。另外,考虑到在线买菜app的特点,还需要引入一些额外的技术,如支付接口和物流配送等。 ### 回答3: 使用uni-app开发在线买菜app的后端可以选择使用以下技术: 1. Node.js:Node.js是一种基于Chrome V8引擎的JavaScript运行时,可以用于构建高性能的网络应用程序。使用Node.js可以方便地构建服务器端逻辑和数据处理功能,并且可以与Uni-app的前端代码进行数据交互。 2. Express.js:Express.js是Node.js的轻量级Web应用框架,可以帮助开发人员快速搭建基于Node.js的后端服务器。Uni-app的前端代码可以通过HTTP请求与Express.js后端进行数据交互。 3. MongoDB:MongoDB是一个非关系型数据库,支持存储海量的非结构化数据。使用MongoDB可以存储和查询用户信息、商品信息、订单信息等数据,并通过相应的API接口提供给Uni-app前端进行操作。 4. RESTful API:使用RESTful API可以定义一组规范的接口,通过HTTP协议进行通信。Uni-app的前端可以通过调用这些API来获取后端数据,实现用户注册、登录、下单等功能。 5. 阿里云/腾讯云等云服务平台:云服务平台提供了丰富的基础设施和服务,如云服务器、云数据库、负载均衡等。使用云服务平台可以轻松搭建和部署Uni-app的后端应用,提高应用的可用性和可扩展性。 综上所述,使用uni-app开发在线买菜app的后端可选择使用Node.js、Express.js、MongoDB等技术,并结合RESTful API和云服务平台来提供稳定高效的后端服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小徐博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值