【云岚到家】-day02-客户管理-认证授权
第二章 客户管理
1.认证模块
1.1 需求分析
1.基础概念
一般情况有用户交互的项目都有认证授权功能,首先我们要搞清楚两个概念:认证和授权
认证: 就是校验用户的身份是否合法,常见的认证方式有账号密码登录、手机验证码登录等
授权:则是该用户登录系统成功后当用户去点击菜单或操作数据时系统判断该用户是否有权限,有权限则允许继续操作,没有权限则拒绝访问
2.小程序认证
本项目包括四个端:用户端(小程序)、服务端(app)、机构端(PC)、运营管理端(PC)
分别对应四类用户角色:家政需求方即c端用户,家政服务人员、家政服务公司(机构)、平台运营人员
用户端通过小程序使用平台,初次使用小程序会进行认证,如下图:

点击“快速登录”弹出服务条款窗口

点击“同意”进行认证,系统与微信进行交互获取用户在小程序中的唯一标识openid
初次认证通过会自动注册用户信息到本平台
下边是小程序的认证流程:

3.手机验证码认证
服务人员通过app登录采用手机验证码认证方式,输入手机号、发送验证码,验证码校验通过则认证通过,初次认证通过将自动注册服务人员信息

手机验证码认证流程如下:

4.账号密码认证
机构端认证方式是账号密码认证方式,通过pc浏览器进入登录界面输入账号和密码登录系统

机构端提供单独的注册页面,输入手机号,接收验证码进行注册

管理端的认证方式也是账号密码方式,管理端的账号由管理员在后台录入,不提供注册页面

1.2 小程序认证
1.2.1 测试小程序认证
1.参考官方流程
小程序认证流程需要三部分:
小程序:即前端程序
开发者服务器:后端微服务程序
微信接口服务:即微信服务器

1.前端调用wx.login()获取登录凭证code
2.前端请求后端进行认证,发送code
3.后端请求微信获取openid,发送appid、app密钥、code参数,微信返回openid
4.后端生成认证成功凭证返回给前端。
5.前端存储用户认证成功凭证
2.申请小程序账号
开发小程序首先要申请小程序账号,点击注册小程序(https://mp.weixin.qq.com/wxopen/waregister?action=step1)填写信息

进入邮箱激活小程序,进入下一步信息登记,选择“个人”
进入小程序管理界面

填写小程序信息,点击上图中小程序信息栏目的“去填写按钮”,小程序名称一定谨慎填写,每年是有一定修改次数限制的
注意:小程序名称不能重复

下边配置最关键的appid和密钥,通过左侧菜单找到开发管理菜单,点击“开发管理”菜单进入下图界面,点击“开发设置”

使用自己的微信扫描二维码生成密钥成功,点击“复制”将密钥和AppID妥善保存,开发小程序要使用
AppID(小程序ID):wxec21e59c983b806f
AppSecret(小程序密钥) :758cd204a5e49a9c5df95e1b48ca4d70

3.创建jzo2o-customer
小程序账号申请成功,下边部署配置后端程序
客户管理工程jzo2o-customer提供了小程序认证接口支持,jzo2o-customer通过jzo2o-publics请求微信获取openid
下边创建jzo2o-customer工程,创建过程参考jzo2o-foundations工程,工程创建完成修改bootstrap-dev.yml配置文件:
接下来进入nacos修改jzo2o-publics.yaml中小程序的appid和密钥

小程序认证需要启动的微服务包括:网关jzo2o-gateway、客户管理jzo2o-customer、公共服务jzo2o-publics,将其它服务也正常启动,启动这三个微服务成功,下边开始部署前端
4.部署前端
用户端是基于微信小程序开发的,首先需要下载并安装微信开发者工具
配置小程序开发环境
打开微信开发者工具,初次使用弹出身份确认,如下图,使用申请小程序账号时用的微信进行扫码,扫码通过进入下边的界面:

进入添加小程序项目界面
目录:选择小程序前端工程的 project-xzb-xcx-uniapp-java\unpackage\dist\dev\mp-weixin目录
AppID:填写申请小程序号获取的AppID
选择不使用云服务

修改project-xzb-xcx-uniapp-java\unpackage\dist\dev\mp-weixin\utils\env.js 配置文件,指定后端网关的地址

设置代理


如果要选择其它目录可以关闭当前项目,重新选择

5.编译运行
小程序认证需要启动的微服务包括:网关jzo2o-gateway、客户管理jzo2o-customer、公共服务jzo2o-publics,保证这三个服务全部启动
注意:保证jzo2o-publics服务配置高德地图key(参考:高德地图web服务配置文档)、微信的appid和app密钥。配置完成将jzo2o-publics服务重新启动。
首先清除缓存

然后编译运行

编译运行到登录界面

点击“快速登录”按照前边讲的小程序认证流程进行操作,请求认证接口进行认证,进入调试器–>Network观察请求记录

认证接口的地址是:/customer/open/login/common/user
此接口最终从微信拿到用户的openid(微信给用户分配的唯一标识),并将openid存储到数据库,认证通过生成token令牌返回给前端
认证通过进入下边的界面

7.小结
首先申请小程序账号,然后配置后端工程(网关jzo2o-gateway、客户管理jzo2o-customer、公共服务jzo2o-publics)、保证启动成功
再部署前端工程,这里需要安装微信小程序开发工具等,最后编译运行前端工程测试认证流程,测试过程可进入调试界面跟踪前后端的交互数据
1.2.2 阅读代码
1.小程序认证流程
整个过程包括三部分:
小程序:即前端程序
开发者服务器:后端微服务程序
微信接口服务:即微信服务器
具体的流程如下:
1.前端调用wx.login()获取登录凭证code
2.前端请求后端进行认证,发送code
3.后端请求微信获取openid
4.后端生成认证成功凭证返回给前端

根据官方的认证流程我们定义本项目小程序认证的交互流程:
customer工程提供认证接口,publics工程作为一个公共服务提供与微信通信的接口
前端与cutomer交互不与publics交互
token包含用户信息

2.阅读代码
下边根据认证流程阅读代码,我们以断点调试的方式跟踪接口交互过程
customer提供的小程序认证接口
前端点击快速登录,授权获取手机号,请求jzo2o-customer的普通用户登录接口LoginController,普通用户登录接口如下:

customer请求publics申请获取openid
和微信相关的都在publics,publics服务获取openid接口InnerWechatController如下:

publics请求weixin 获取openid

customer收到openid查询数据库获取用户信息并生成token.
openid是微信用户在家政o2o平台的唯一标识,首先根据openid查询jzo2o-customer的common_user表,是否存在用户,如果不存在则自动注册用户信息,用户信息token存储到jzo2o-customer数据库的common_user表中

common_user表的结构如下:
create table `jzo2o-customer`.common_user
(id bigint not null comment '用户id' constraint `PRIMARY` primary key,status int default 0 not null comment '状态,0:正常,1:冻结',nickname varchar(255) null comment '昵称',phone varchar(25) null comment '电话',avatar varchar(255) null comment '头像',open_id varchar(100) null,account_lock_reason varchar(255) null comment '账号冻结原因',create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',is_deleted int default 0 not null
) charset = utf8mb4;
认证通过生成用户token返回给前端

token令牌的格式我们使用的是JWT格式,JWT是一种常用的令牌格式,它可以防篡改
在JWT令牌中存储了当前登录用户的信息(json),包括如下属性:
用户id: id,对应common_user表的主键
用户名称:String name,对应common_user表的nickname字段
用户头像:String avatar,对应common_user表的avatar字段
用户类型:Integer userType,c端用户的用户类型代码为1,具体定义在common.constants.UserType中
网关对token统一校验
在网关对token进行解析校验,token不合法直接返回失败信息,token合法解析出用户信息放在http的head中继续请求微服务

在微服务中解析http头信息中的用户信息,写入ThreadLocal方便应用程序使用

1.3 手机验证码认证
1.3.1 测试手机验证码认证
服务人员使用APP登录平台使用的是手机验证码认证方式,整个认证流程也需要部署前端、后端
客户管理工程jzo2o-customer与公共服务jzo2o-publics提供手机验证码的接口,这两个服务在小程序认证时已经部署这里不再部署,我们只需要部署前端工程即可
1.部署前端
服务端的前端工程需要使用 HBuilder 3.8.7 X 软件编译运行,启动HBuilderX,打开project-xzb-app-uniapp-java目录

配置网关地址,配置完成,使用HBuilderX运行到浏览器

运行成功进入登录页面:

2.认证测试
首先输入手机号,服务人员的信息存储在jzo2o-customer数据库的serve_provider表中,从表中找一个手机号录入
点击发送验证码,此时前端请求后端发送验证码,在开发环境我们从控制台获取验证码,稍后后带大家分析发送验证码的程序
注意此时因为请求后端发送验证码我们观察在浏览器的Network窗口有一条记录,如下图,该请求必须响应状态为200方可正常发送验证

从控制台获取刚才发送的验证码

将从控制台获取的验证码填入验证码输入框

点击登录进行认证,认证过程会先校验验证码是否正确,如果验证码正确再根据手机号查询serve_provider表是否存在相应记录且用户未被冻结,全部成功则认证通过。
认证通过进入首页。

1.3.2 阅读代码
1.手机验证码认证流程
customer工程提供认证接口,publics工程作为一个公共服务提供与发送验证码接口

2.阅读代码
1.找到具体的接口
前端请求publics服务发送验证码接口:publics/sms-code/send


具体发送验证码逻辑:

前端请求customer服务的认证接口:/customer/open/login/worker,代码如下:

机构和和服务人员认证接口是同一个,根据类型判断是机构还是服务人员,下图中红色箭头指向的代码是服务人员认证的方法

customer服务请求publics服务校验验证码

publics服务提供校验验证码接口,如下图:

2.具体校验验证码逻辑
具体的验证码校验逻辑是先查询redis中的正确的验证码,再和用户输入的进行对比,如果不一致则说明输入错误,输入正确删除验证码

在使用redisTemplate时需要在工程中引入下边的依赖:
<dependency><groupId>com.jzo2o</groupId><artifactId>jzo2o-redis</artifactId>
</dependency>
在jzo2o-redis中定义了redisTemplate的定义,如下图:

在使用时注入上图中定义的redisTemplate即可
在测试验证码发送时可以打开redis进行跟踪,下图显示了存入redis中的验证码,注意观察key和value:

3.自动注册
校验验证码完成customer服务根据手机号查询数据库,如果用户冻结则认证失败,如果用户不存在则自动注册

服务人员和机构都存储到serve_provider表,结果如下:
create table `jzo2o-customer`.serve_provider
(id bigint not null comment '主键' constraint `PRIMARY` primary key,code varchar(255) null comment '编号',type int not null comment '类型,2:服务人员,3:服务机构',name varchar(255) null comment '姓名',phone varchar(255) not null comment '电话',avatar varchar(255) null comment '头像',status int not null comment '状态,0:正常,1:冻结',settings_status int default 0 null comment '首次设置状态,0:未完成设置,1:已完成设置',password varchar(255) null comment '机构登录密码',account_lock_reason varchar(255) null comment '账号冻结原因',score double null comment '综合评分',good_level_rate varchar(50) null comment '好评率',create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',is_deleted int default 0 not null comment '是否已删除,0:未删除,1:已删除',constraint serve_provider_phone_type_uindex unique (phone, type)
) comment '服务人员/机构表' charset = utf8mb4;
最后生成token返回给前端

注意:为了方便验证码测试前端会自动填入123456,更改验证码发送接口固定生成的验证码为123456

1.4 完成机构注册功能开发
界面原型:进入登录页面,点击“去注册”进入注册页面


接口定义如下:
接口地址:POST/customer/open/serve-provider/institution/register

注意:机构端注册和服务端注册完成要向serve_provider表写入数据,具体查阅上图的方法。
密码加密方式:使用BCrypt方式,BCrypt是一种密码哈希函数,通常用于存储用户密码的安全性。它是基于 Blowfish 密码算法的一种单向哈希函数

测试方法:
public static void main(String[] args) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();/**$2a$10$1sp7I0OdYH3Azs/2lK8YYeuiaGZzOGshGT9j.IYArZftsGNsXqlma$2a$10$m983E2nmJ7ITlesbXzjbzO/M7HL2wP8EgpgX.pPACDm1wG38Lt.na$2a$10$rZvathrW98vVPenLhOnl0OMpUtRTdBkWJ45IkIsTebITS9AFgKqGK$2a$10$2gaMKWCRoKdc42E0jsq7b.munjzOSPOM4yr3GG9M6194E7dOH5LyS$2a$10$I/n93PIKpKL8m4O3AuT5kuZncZhfqV51bfx5sJrplnYoM7FimdboC*/for (int i = 0; i < 5; i++) {//对密码进行哈希String encode = passwordEncoder.encode("11111");System.out.println(encode);}//校验哈希串和密码是否匹配boolean matches = passwordEncoder.matches("11111", "$2a$10$m983E2nmJ7ITlesbXzjbzO/M7HL2wP8EgpgX.pPACDm1wG38Lt.na");System.out.println(matches);
}
根据上边的测试代码可知,BCrypt的使用方法如下:
用户输入密码,通过passwordEncoder.encode(“输入的密码”)得到哈希串,将哈希串存储到数据库。
用户登录校验密码,从数据库取出哈希串,连同用户输入的密码,调用下边的方法:
passwordEncoder.matches(“用户输入的密码”, “从数据库查询的密码哈希串”);
1.4.1 mapper
单表查询,用mybatisplus即可
1.4.2 service
在com.jzo2o.customer.service.IServeProviderService接口:
package com.jzo2o.customer.service;/*** 服务人员/机构表 服务类*/
public interface IServeProviderService extends IService<ServeProvider> {/*** 机构人员注册*/ServeProvider registerInstitution(InstitutionRegisterReqDTO institutionRegisterReqDTO);}
实现:
package com.jzo2o.customer.service.impl;/*** 服务人员/机构表 服务实现类*/
@Service
public class ServeProviderServiceImpl extends ServiceImpl<ServeProviderMapper, ServeProvider> implements IServeProviderService {/*** 机构人员注册*/@Overridepublic ServeProvider registerInstitution(InstitutionRegisterReqDTO institutionRegisterReqDTO) {//1.校验手机验证码是否正确//1.1.数据校验if(StringUtils.isEmpty(institutionRegisterReqDTO.getVerifyCode())){throw new BadRequestException("验证码错误,请重新获取");}//1.2.远程调用publics服务校验验证码是否正确boolean verifyResult = smsCodeApi.verify(institutionRegisterReqDTO.getPhone(), SmsBussinessTypeEnum.INSTITION_REGISTER, institutionRegisterReqDTO.getVerifyCode()).getIsSuccess();if(!verifyResult) {throw new BadRequestException("验证码错误,请重新获取");}//2.检查手机号是否被注册过BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String encode = passwordEncoder.encode(institutionRegisterReqDTO.getPassword());ServeProvider serveProvider = add(institutionRegisterReqDTO.getPhone(), UserType.INSTITUTION, encode);return serveProvider;}}
1.4.3 测试
手机号随便输入


成功返回,查看数据库

1.5 完成忘记密码功能开发
界面原型:进入登录页面,点击“忘记密码”进入找回密码页面


接口定义如下:
接口名称:机构登录密码重置接口
接口路径:POST/customer/agency/serve-provider/institution/resetPassword

设计须知:
首先校验验证码是否正确
校验手机号是否存在数据库
通过校验最后修改密码,密码的加密方式参考机构注册接口
1.5.1 mapper
单表查询,用mybatisplus即可,不用自己去写SQL语句
1.5.2 service
在com.jzo2o.customer.service.IServeProviderService接口
package com.jzo2o.customer.service;/*** 服务人员/机构表 服务类*/
public interface IServeProviderService extends IService<ServeProvider> {/*** 忘记密码*/ServeProvider resetPassword(InstitutionResetPasswordReqDTO institutionResetPasswordReqDTO);
}
InstitutionResetPasswordReqDTO,前端传递过来的
package com.jzo2o.customer.model.dto.request;@Data
@ApiModel("机构密码重置接口")
public class InstitutionResetPasswordReqDTO {@ApiModelProperty(value = "新密码",required = true)private String password;@ApiModelProperty(value = "手机号",required = true)private String phone;@ApiModelProperty(value = "短信验证码",required = true)@NotNull(message = "验证码错误,请重新输入")private String verifyCode;}
实现:
package com.jzo2o.customer.service.impl;@Service
public class ServeProviderServiceImpl extends ServiceImpl<ServeProviderMapper, ServeProvider> implements IServeProviderService {/*** 忘记密码*/@Overridepublic ServeProvider resetPassword(InstitutionResetPasswordReqDTO institutionResetPasswordReqDTO) {//0.校验手机号是否存在ServeProvider existServeProvider = lambdaQuery().eq(ServeProvider::getPhone, institutionResetPasswordReqDTO.getPhone()).one();if (existServeProvider == null) {throw new BadRequestException("手机号不存在");}//1.校验手机验证码是否正确//1.1.数据校验if (StringUtils.isEmpty(institutionResetPasswordReqDTO.getVerifyCode())){throw new BadRequestException("验证码不能为空");}//1.2.远程调用publics服务校验验证码是否正确boolean verifyResult = smsCodeApi.verify(institutionResetPasswordReqDTO.getPhone(), SmsBussinessTypeEnum.INSTITUTION_RESET_PASSWORD, institutionResetPasswordReqDTO.getVerifyCode()).getIsSuccess();if(!verifyResult) {throw new BadRequestException("验证码错误,请重新获取");}//2.修改密码BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String encode = passwordEncoder.encode(institutionResetPasswordReqDTO.getPassword());boolean update = lambdaUpdate().eq(ServeProvider::getPhone, institutionResetPasswordReqDTO.getPhone()).set(ServeProvider::getPassword, encode).update();if (!update) {throw new BadRequestException("修改密码失败");}existServeProvider.setPassword(encode);return existServeProvider;}}
1.5.3 controller
在com.jzo2o.customer.controller.agency.ServeProviderController中
package com.jzo2o.customer.controller.agency;/*** 服务人员/机构表 前端控制器*/
@RestController("agencyServeProviderController")
@RequestMapping("/agency/serve-provider")
@Api(tags = "机构端 - 服务人员或机构相关接口")
public class ServeProviderController {@Resourceprivate IServeProviderService serveProviderService;@PostMapping("/institution/resetPassword")@ApiOperation("机构人员重置密码")public void resetPassword(@RequestBody InstitutionResetPasswordReqDTO institutionResetPasswordReqDTO) {serveProviderService.resetPassword(institutionResetPasswordReqDTO);}}
相关文章:
【云岚到家】-day02-客户管理-认证授权
第二章 客户管理 1.认证模块 1.1 需求分析 1.基础概念 一般情况有用户交互的项目都有认证授权功能,首先我们要搞清楚两个概念:认证和授权 认证: 就是校验用户的身份是否合法,常见的认证方式有账号密码登录、手机验证码登录等 授权:则是该用…...
【达梦数据库】两地三中心环境总结
目录 架构监视器位置异步备库同步频率配置:dmtimer.ini断网测试异地切换过程&回切:允许丢数据模式切换回切 架构 2(1主1实时备库)1(实时备库)1(异步备库),分别为节点1、2、3、4监视器位置 …...
【springboot 集成 mybatis-plus】
springboot 集成 mybatis-plus 前言实战代码生成器自动填充字段 前言 正如MyBatis-Plus官网所说,MyBatis-Plus 是一个 MyBatis 的增强工具,提供了强大的CRUD操作,支持主键自动生成,代码生成器,自动填充字段等等&#…...
深入浅出 Go语言并发安全字典 sync.Map:原理、使用与优化
深入浅出 Go语言并发安全字典 sync.Map:原理、使用与优化 背景介绍 Go语言作为一种高效的并发编程语言,其标准库中提供了丰富的并发工具,如sync.WaitGroup、sync.Mutex等。然而,在实际开发中,我们经常需要在多个goroutine之间共享数据,这就涉及到并发安全的问题。传统的…...
【Go】Go数据类型详解—指针
1. 前言 在我看来,一门编程语言语法的核心就在于数据类型。而各类编程语言的基本数据类型大致相同:int整型、float浮点型、string字符串类型、bool布尔类型,但是在一些进阶数据类型上就有所不同了。本文将会介绍Go语言当中核心的数据类型——…...
道格拉斯-普克算法(DP)轮廓点精简(Python)
1、介绍 道格拉斯-普克算法由David H. Douglas和Thomas K. Peucker于1973年提出,主要用于简化曲线或折线。而实际中,激光点云的边缘点非常粗糙,如果直接将点进行连接,锯齿问题严重。经过DP算法处理后,数据显示会比较光…...
WPF如何跨线程更新界面
WPF如何跨线程更新界面 在WPF中,类似于WinForms,UI控件只能在UI线程(即主线程)上进行更新。WPF通过Dispatcher机制提供了跨线程更新UI的方式。由于WPF的界面基于Dispatcher线程模型,当你在非UI线程(例如后…...
Ubuntu 24.04 LTS 服务器折腾集
目录 Ubuntu 更改软件源Ubuntu 系统语言英文改中文windows 远程链接 Ubuntu 图形界面Windows 通过 openssh 连接 UbuntuUbuntu linux 文件权限Ubuntu 空闲硬盘挂载到 文件管理器的 other locationsUbuntu 开启 SMB 服务,并通过 windows 访问Ubuntu安装Tailscale&am…...
ROS机器人学习和研究的势-道-术-转型和变革的长期主义习惯
知易行难。说说容易做到难。 例如,不受成败评价影响,坚持做一件事情10年以上,专注事情本身。 机器人专业不合格且失败讲师如何让内心保持充盈的正能量(节选)-CSDN博客 时间积累 注册20年。 创作历程10年。 创作10年…...
Linux 管道操作
Linux 管道操作 在 Linux 中,管道(Pipe)是一个非常强大且常用的功能,它允许将一个命令的输出直接传递给另一个命令作为输入,从而能够高效地处理和分析数据。管道在多个命令之间建立数据流,减少了文件的读写…...
【Python】深入探讨Python中的单例模式:元类与装饰器实现方式分析与代码示例
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 单例模式(Singleton Pattern)是一种常见的设计模式,它确保一个类只有一个实例&…...
imbinarize函数用法详解与示例
一、函数概述 众所周知,im2bw函数可以将灰度图像转换为二值图像。但MATLAB中还有一个imbinarize函数可以将灰度图像转换为二值图像。imbinarize函数是MATLAB图像处理工具箱中用于将灰度图像或体数据二值化的工具。它可以通过全局或自适应阈值方法将灰度图像转换为二…...
【NextJS】PostgreSQL 遇上 Prisma ORM
NextJS 数据库 之 遇上Prisma ORM 前言一、环境要求二、概念介绍1、Prisma Schema Language(PSL) 结构描述语言1.1 概念1.2 组成1.2.1 Data Source 数据源1.2.2 Generators 生成器1.2.3 Data Model Definition 数据模型定义字段(数据)类型和约束关系&…...
ASP.NET Core - 配置系统之配置提供程序
ASP.NET Core - 配置系统之配置提供程序 3. 配置提供程序3.1 文件配置提供程序3.1.1 JSON配置提供程序3.1.2 XML配置提供程序3.1.3 INI配置提供程序 3.2 环境变量配置提供程序3.3 命令行配置提供程序3.4 内存配置提供程序3.5 配置加载顺序 3.6 默认配置来源 3. 配置提供程序 前…...
【LeetCode: 215. 数组中的第K个最大元素 + 快速选择排序】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
【Flink系列】10. Flink SQL
10. Flink SQL Table API和SQL是最上层的API,在Flink中这两种API被集成在一起,SQL执行的对象也是Flink中的表(Table),所以我们一般会认为它们是一体的。Flink是批流统一的处理框架,无论是批处理(…...
JavaScript网页设计案例-JavaScript实现数据脱敏的几种解决方式
数据脱敏是指对数据进行处理,使其在不改变原始数据含义的前提下,降低数据泄露的风险,保护用户隐私。 案例:JavaScript实现数据脱敏 1. 掩码脱敏 掩码脱敏是通过替换或隐藏数据中的部分字符来达到脱敏的效果。常见的掩码方式包括…...
第12篇:从入门到精通:掌握python高级函数与装饰器
第12篇:高级函数与装饰器 内容简介 本篇文章将深入探讨Python中的高级函数与装饰器。您将学习什么是高阶函数,掌握常用的高阶函数如map、filter、reduce的使用方法;理解闭包的概念及其应用;深入了解装饰器的定义与使用ÿ…...
审计文件标识作为水印打印在pdf页面边角
目录 说明 说明 将审计文件的所需要贴的编码直接作为水印贴在页面四个角落,节省辨别时间 我曾经写过一个给pdf页面四个角落加上文件名水印的python脚本,现在需要加一个图形界面进一步加强其实用性。首先通过路径浏览指定文件路径,先检测该路…...
leetcode416.分割等和子集
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 示例 2&…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
Spring AOP代理对象生成原理
代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】,这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...
