自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用FaceIO開(kāi)發(fā)基于人工智能的Web?App用戶認(rèn)證模塊

譯文
開(kāi)發(fā) 前端 人工智能
在Web應(yīng)用項(xiàng)目中可以使用FaceIO的JavaScript庫(kù)實(shí)現(xiàn)用戶認(rèn)證。

譯者 | 李睿

審校 | 重樓

在過(guò)去的Web應(yīng)用信息系統(tǒng)開(kāi)發(fā)中,用戶認(rèn)證是一個(gè)不可或缺的功能模塊。用戶認(rèn)證功能包括用戶注冊(cè)和登錄認(rèn)證。在以往的開(kāi)發(fā)方法中,用戶認(rèn)證功能模塊實(shí)現(xiàn)的常見(jiàn)方式是使用電子郵件和短信進(jìn)行驗(yàn)證。很多用戶的電腦都安裝了攝像頭,采用攝像頭可以充分利用人臉識(shí)別的人工智能技術(shù)來(lái)實(shí)現(xiàn)用戶認(rèn)證。而使用FaceIO的JavaScript庫(kù)在Web應(yīng)用程序項(xiàng)目中可以實(shí)現(xiàn)用戶身份驗(yàn)證。

本文主要介紹如何通過(guò)第三方人工智能服務(wù)接口開(kāi)發(fā)Web應(yīng)用項(xiàng)目的用戶登錄模塊。Web應(yīng)用程序項(xiàng)目的源代碼已上傳到GitHub,并基于MIT協(xié)議。沒(méi)有任何限制。

本項(xiàng)目是一個(gè)簡(jiǎn)單完整的Web微服務(wù)系統(tǒng)。本項(xiàng)目采用前后端分離的開(kāi)發(fā)方法,使用不同的項(xiàng)目文件路徑。

Plain Text 
 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+

這個(gè)Web項(xiàng)目的源代碼包括前端、后端和數(shù)據(jù)庫(kù),是一個(gè)完整的Web應(yīng)用程序信息系統(tǒng)。前端開(kāi)發(fā)使用React,后端開(kāi)發(fā)使用Java和SpringBoot,數(shù)據(jù)庫(kù)使用MySQL。第三方AI業(yè)務(wù)接口使用FaceIO。FaceIO提供了一個(gè)在線JavaScript庫(kù),可以在前端代碼中直接引用。前端引用FaceIO庫(kù)之后,添加少量代碼即可輕松實(shí)現(xiàn)人臉認(rèn)證,在與后端集成后,即可實(shí)現(xiàn)完整的用戶認(rèn)證。前端界面使用CoreUI免費(fèi)模板。

FaceIO的使用并不局限于瀏覽器。它可以在任何瀏覽器上運(yùn)行,包括IE、Chrome、Firefox和Safari。而且,所有人工智能業(yè)務(wù)處理都是在FaceIO的服務(wù)器上完成的,所以FaceIO需要能夠訪問(wèn)用戶當(dāng)前瀏覽器上的攝像頭。

如何在前端React框架中使用FaceIO庫(kù)

步驟1:安裝和配置Node.js環(huán)境

從Node.js官方網(wǎng)站下載對(duì)應(yīng)版本的Node.js壓縮包。這里使用的版本是V18.0.0。如果用戶想運(yùn)行發(fā)布的這個(gè)開(kāi)源網(wǎng)絡(luò)項(xiàng)目,最好也使用V18.0.0。由于Node.js版本的迭代速度相對(duì)較快,如果使用其他版本,這一開(kāi)源Web項(xiàng)目中使用的本地JavaScript庫(kù)可能不兼容,可能無(wú)法運(yùn)行。

在下載Node.js壓縮包之后,將壓縮包解壓到英文目錄下。因?yàn)槭褂肐ntelliJ IDEA開(kāi)發(fā)前端React,所以需要在IntelliJ IDEA中配置Node.js和NPM,并指定Node.js的安裝目錄。

在Intelli J IDEA中配置Node.js和NPM后,用戶可以通過(guò)IntelliJ IDEA工具創(chuàng)建ReactApp項(xiàng)目。

步驟2:在FaceIO中申請(qǐng)公共ID

FaceIO提供了一個(gè)在線JavaScript庫(kù)。如果想使用FaceIO提供的人工智能服務(wù),則需要為其APP申請(qǐng)一個(gè)公共ID。在登錄之前,首先注冊(cè)一個(gè)帳戶,然后根據(jù)項(xiàng)目創(chuàng)建一個(gè)應(yīng)用程序以獲得公共ID。這個(gè)公共ID需要寫(xiě)在ReactApp項(xiàng)目的代碼中。在申請(qǐng)公共ID時(shí),F(xiàn)aceIO將為應(yīng)用程序提供一個(gè)免費(fèi)的公共ID版本,并對(duì)使用次數(shù)進(jìn)行限制。

步驟3:在React應(yīng)用程序項(xiàng)目中使用FaceIO

外部JavaScript庫(kù)地址由FaceIO提供。

JavaScript 
 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之后,定義常量就可以使用了。代碼如下所示:

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

fioab497是應(yīng)用注冊(cè)后的公共ID。用戶需要替換應(yīng)用程序的公共ID。

需要注意的是,在上面代碼React的鉤子函數(shù)useEffect()中,有一行代碼//eslint-disable-next-line。如果用戶已經(jīng)在開(kāi)發(fā)環(huán)境中安裝了eslint插件,則需要添加這行代碼。如果沒(méi)有這行代碼,eslint檢測(cè)將認(rèn)為存在錯(cuò)誤。錯(cuò)誤提示如下:

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

在開(kāi)發(fā)環(huán)境中,Web項(xiàng)目將無(wú)法運(yùn)行。因此,需要添加這一行注釋代碼來(lái)讓eslint跳過(guò)下一行代碼的檢測(cè)。

FaceIO提供了人臉注冊(cè)函數(shù)enroll()。代碼的使用方式如下:

JavaScript 
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);
 })
 }

在上面的代碼中,函數(shù)enroll()以JSON字符串格式輸入數(shù)據(jù),并傳遞給FaceIO的人工智能接口。UserInfo是FaceIO人臉驗(yàn)證后返回的數(shù)據(jù)對(duì)象。handllogin()是一個(gè)用戶定義的函數(shù),用于在接收到FaceIO返回的數(shù)據(jù)對(duì)象后與后端通信。當(dāng)然,用戶也可以根據(jù)自己的開(kāi)發(fā)情況,設(shè)置其他自定義函數(shù)來(lái)處理FaceIO返回的數(shù)據(jù)對(duì)象。

在函數(shù)enroll()輸入的JSON字符串格式數(shù)據(jù)中,還可以添加自定義JSON字符串?dāng)?shù)據(jù)。代碼如下所示

JavaScript 
 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可以返回的數(shù)據(jù)節(jié)點(diǎn)。在“有效負(fù)載”中,可以添加需要返回的JSON格式數(shù)據(jù),并根據(jù)開(kāi)發(fā)需求定制數(shù)據(jù)內(nèi)容。

調(diào)用函數(shù)enroll()后,瀏覽器將顯示FaceIO提供的人機(jī)交互用戶界面,并在瀏覽器提示符下啟動(dòng)攝像頭。需要點(diǎn)擊“是”。FaceIO提供的用戶界面會(huì)自動(dòng)在當(dāng)前攝像頭前確認(rèn)用戶的臉兩次,并要求當(dāng)前用戶確認(rèn)兩次PIN碼的設(shè)置。輸入的PIN碼將用于面部認(rèn)證。

FaceIO提供了人臉認(rèn)證函數(shù)authenticate()。代碼的使用方式如下:

JavaScript 
 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);
 })
 }

在調(diào)用authenticate()函數(shù)之后,瀏覽器將顯示FaceIO提供的人機(jī)交互用戶界面,啟動(dòng)攝像頭,并要求當(dāng)前登錄用戶輸入人臉注冊(cè)時(shí)設(shè)置的PIN碼。

根據(jù)FaceIO返回的數(shù)據(jù),自定義函數(shù)handleLogin()被傳遞到后端。后端接收數(shù)據(jù),分析數(shù)據(jù),并將結(jié)果返回給前端。前端執(zhí)行后續(xù)業(yè)務(wù)邏輯。如果用戶身份驗(yàn)證成功,后端將向前端返回令牌數(shù)據(jù)。在前端確認(rèn)登錄成功后,頁(yè)面跳轉(zhuǎn)到Dashboard完成整個(gè)用戶身份驗(yàn)證過(guò)程。

前端接收到令牌數(shù)據(jù)后,將令牌數(shù)據(jù)保存在用戶當(dāng)前瀏覽器的會(huì)話存儲(chǔ)中。在會(huì)話存儲(chǔ)中自定義了一個(gè)名為“Authorization”的項(xiàng)來(lái)存儲(chǔ)令牌數(shù)據(jù)。保存令牌數(shù)據(jù)的函數(shù)代碼如下:

JavaScript 
1 const setAuthorization = (Auth) => {
2 sessionStorage.setItem('Authorization',Auth)
3 }

獲取Token數(shù)據(jù)的函數(shù)代碼如下:

JavaScript 
1function getAuthorization () {
2 let Author = sessionStorage.getItem('Authorization')
3 if (Author === null) return ''
4 return Author
5 }

已經(jīng)在系統(tǒng)中設(shè)置了自動(dòng)加載令牌數(shù)據(jù)。在后續(xù)的業(yè)務(wù)處理中,當(dāng)訪問(wèn)后端API時(shí),令牌數(shù)據(jù)將自動(dòng)放置在請(qǐng)求頭的授權(quán)中。代碼如下所示:

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

如何在后端完成用戶認(rèn)證

在Web項(xiàng)目中,使用SpringBoot作為后臺(tái),開(kāi)發(fā)語(yǔ)言為Java 1.8。在Spring框架中,創(chuàng)建一個(gè)處理用戶登錄身份驗(yàn)證的控制層類。這個(gè)LoginController類也是一個(gè)用于處理用戶登錄身份驗(yàn)證的API接口。代碼如下:

Java 
 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) {
 ...
 }
15 @PostMapping("/signIn")
16 public AjaxResult signIn(@RequestBody JSONObject userInfo) {
17 ...
18 }
19 }

在上面的代碼中,@RequestMapping("/login")表示整個(gè)LoginController類的API路徑。

@PostMapping("/signUp")表示用戶注冊(cè)的API路徑,接收POST數(shù)據(jù)請(qǐng)求,使用函數(shù)signUp()處理用戶注冊(cè)。完整的API路徑是/login/signUp。

@PostMapping("/signIn")表示用戶身份驗(yàn)證的API路徑。它接收POST數(shù)據(jù)請(qǐng)求。函數(shù)signIn()用于處理用戶身份驗(yàn)證。完整的API路徑是/login/signIn。

在函數(shù)signUp()或signIn()中,解析前端React傳遞的JSON格式數(shù)據(jù)。從JSON數(shù)據(jù)中提取nodefacialId的值。FacialId是FaceIO成功驗(yàn)證用戶時(shí)返回的唯一標(biāo)識(shí)符。該ID是唯一的。在這個(gè)Web項(xiàng)目中,通過(guò)“facialId”判斷用戶,并通過(guò)facialId識(shí)別用戶。

需要注意的是,在這個(gè)Web項(xiàng)目中,JSON格式的數(shù)據(jù)從前端傳輸?shù)胶蠖耸敲魑牡?,沒(méi)有進(jìn)行數(shù)據(jù)加密。如果使用它,可以添加安全函數(shù)來(lái)加密JSON格式的數(shù)據(jù)。前端加密完成后,消息從前端傳輸?shù)胶蠖恕T诤蠖私饷芎?,將解析JSON格式數(shù)據(jù)。加密方法有很多種。在此推薦RSA算法。RSA算法是一種非對(duì)稱加解密算法。在后端,也就是在用戶訪問(wèn)Web時(shí),服務(wù)器端生成一對(duì)RSA密鑰,包括公鑰和私鑰,并將公鑰提供給前端。前端使用公鑰對(duì)JSON格式的數(shù)據(jù)進(jìn)行加密,然后傳輸?shù)胶蠖?。后端根?jù)私鑰對(duì)其進(jìn)行解密。在解密之后,解析JSON格式數(shù)據(jù)。這可以最大限度地保護(hù)“facialId”的值不被輕易攔截。

在后端,在用戶被facialId成功識(shí)別之后。使用JWT方法保存當(dāng)前登錄用戶的信息。JWT Utils類中的函數(shù)getToken(AppUser用戶)獲取當(dāng)前用戶的令牌。使用facialId的值作為簽名密鑰。代碼如下所示

Java 
 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()));
 }
 }

在后端獲取當(dāng)前登錄用戶的令牌后,將令牌數(shù)據(jù)返回給前端。

用戶身份驗(yàn)證成功后,后端將在每個(gè)后續(xù)API請(qǐng)求中接收用于用戶身份驗(yàn)證的Token數(shù)據(jù)。已經(jīng)創(chuàng)建了一個(gè)攔截器類JWTInterceptor,用于在每個(gè)API請(qǐng)求之前驗(yàn)證令牌數(shù)據(jù)。代碼如下所示:

Java 
 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();
 }
 }
 }

除了在前端提供易于使用的功能之外,F(xiàn)aceIO還提供了REST API,允許從后端管理應(yīng)用程序。每個(gè)FaceIO應(yīng)用程序都會(huì)自動(dòng)分配一個(gè)API密鑰可以從FaceIO控制臺(tái)的應(yīng)用程序管理器中檢索這一密鑰。API鍵允許用戶從專用的后端環(huán)境以編程方式管理應(yīng)用程序,可以使用SpringBoot的RestTemplate輕松實(shí)現(xiàn)它。因?yàn)檫@一項(xiàng)目是一個(gè)簡(jiǎn)單的應(yīng)用程序,所以沒(méi)有在這方面使用它。如果用戶感興趣,可以訪問(wèn)FaceIO其余API的在線文檔。

如何設(shè)計(jì)數(shù)據(jù)庫(kù)

在這個(gè)Web項(xiàng)目中,數(shù)據(jù)庫(kù)使用MySQL。為了配合人臉識(shí)別,設(shè)計(jì)了一個(gè)簡(jiǎn)單的用戶表。創(chuàng)建表SQL語(yǔ)句

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
 )

數(shù)據(jù)表中的字段facal_id用于存儲(chǔ)FaceIO返回的唯一用戶ID。這是一個(gè)簡(jiǎn)單的用戶數(shù)據(jù)表。沒(méi)有用戶密碼字段或用戶手機(jī)字段。該用戶數(shù)據(jù)表僅使用字段“facal_id”完成登錄用戶的認(rèn)證和識(shí)別。

用戶在FaceIO完成注冊(cè)后,F(xiàn)aceIO返回的JSON字符串?dāng)?shù)據(jù)中包含“details”節(jié)點(diǎn),即FaceIO人工智能識(shí)別的當(dāng)前用戶的年齡和性別。將它存儲(chǔ)在用戶數(shù)據(jù)表中的“年齡”和“性別”字段中,這是目前的開(kāi)發(fā)方法。

當(dāng)然,也可以保留以前的用戶認(rèn)證的開(kāi)發(fā)方法,同時(shí)仍然保留登錄密碼和SMS認(rèn)證。在原有開(kāi)發(fā)方法的基礎(chǔ)上,增加了FaceIO的人臉認(rèn)證方法。在原有的用戶數(shù)據(jù)表中,添加字段facal_id綁定人工智能的人臉識(shí)別。

原文標(biāo)題:Using the JavaScript library of FaceIO to implement user authentication in a web application project作者:jianxiang sun

責(zé)任編輯:華軒 來(lái)源: 51CTO
相關(guān)推薦

2020-07-03 09:42:13

人工智能機(jī)器學(xué)習(xí)技術(shù)

2018-07-05 14:52:05

2024-03-15 14:26:28

2021-08-26 14:16:28

物聯(lián)網(wǎng)人工智能IoT

2022-08-01 10:41:03

人工智能認(rèn)證人工智能

2023-06-06 16:27:06

人工智能Web 3.0

2022-07-29 15:47:25

人工智能AI

2020-03-25 09:53:33

人工智能AI技術(shù)

2019-04-01 15:46:49

AI微軟Outlook on

2021-07-12 14:16:01

人工智能AI深度學(xué)習(xí)

2024-04-24 14:11:07

2023-06-19 15:46:25

2022-06-20 11:05:58

通用人工智能機(jī)器人

2020-09-16 10:37:10

人工智能AI技術(shù)

2020-11-23 11:11:29

人工智能

2016-12-26 14:55:06

人工智能現(xiàn)狀

2021-03-22 12:08:30

人工智能

2018-08-17 15:17:56

人工智能層次極端

2019-02-14 09:10:52

人工智能AI

2019-02-21 10:02:35

人工智能AI機(jī)器學(xué)習(xí)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)