本文主要分享了如何设计一个可扩展的登录功能。
一、多种登录方式(需要有一个唯一值来绑定各种登录方式,目前业界用的比较多的是手机号)
1.用户名 密码登录
最原始的登录方式,这种登录方式与注册功能是分开的,业界慢慢放弃这种方式了
2.手机号 验证码登录
业界大部分使用的登录方式,这种登录方式与注册功能是一体实现的,但这种方式存在短信验证码获取体验问题
3.本机号码一键登录
基于方式2的优化,把登录体验做到极致
4.第三方授权登录(如微信、微、QQ等)
登录方式的优化,登录体验可以做到跟方式3一样,这里的授权是指微信、微、QQ等第三方平台授权登录时获取的code,根据这个code可以获取第三方平台的用户信息(如openid、unionid)
5.手机号 验证码登录 绑定第三方授权
作为方式4的补充,一般是方式4完成的情况下进行。通常情况下授权登录后并不知道用户是否已存在账号,需要引入手机号来做唯一值校验
二、在微服务中设计一个认证服务,以上的登录方式统一在认证服务中实现
1.C端API大致可以简单分为两种,一种是需用户登录后可访问,另一种是无需登录也可访问
2.请求不带token,肯定是未登录的;带了token,也不一定登录的,可能token是失效的
3.如果带了token,在网关进行统一处理,解析token获取里面的用户ID(生成token时设置进去的)并设置到header在微服务内部传递,如果token过期了则不要设置到header
4.BFF层的微服务自行根据header能否取到用户ID来判断用户是否登录,如果是需要登录后才能访问的API且无用户ID,则响应固定的错误码,与前端同事约定响应该错误码就引导登录
5.登录的请求转发到认证服务,注册/登录一体化,响应token给到前端,前端把token做本地存储,后续的所有请求都带上token
三、核心代码
1.登录接口代码
2.解析token获取用户ID并将设置到header
3.根据header有无用户ID拦截需登录API
四、存储表结构
CREATE TABLE `bu_user_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`nickname` varchar(32) DEFAULT NULL COMMENT '昵称',
`avator` varchar(32) DEFAULT NULL COMMENT '头像',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
CREATE TABLE `bu_user_oauth` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`user_id` int(11) NOT NULL COMMENT 'bu_user_info.id',
`identity_type` varchar(32) NOT NULL COMMENT '账号类型(mobile:手机号,wx-unionid:微信unionid,wx-openid-miniapp:微信小程序openid,wx-openid-mp:微信公众号openid,email:邮箱,username:用户名,sina:新浪微,qq:QQ)',
`identifier` varchar(32) NOT NULL COMMENT '手机号、邮箱、用户名或第三方应用的唯一标识',
`certificate` varchar(255) DEFAULT NULL COMMENT '凭证(站内的保存密码,站外的不保存或保存token)',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uniq_ui_it` (`user_id`,`identity_type`),
UNIQUE KEY `uniq_identifier_it` (`identifier`,`identity_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户认证表';
怎么样?如果你觉得有用的话,还不快快收藏起来!!!
附:涉及的代码目录
github:https://github/897665787/springcloud-template
gitee:https://gitee/jq_di/springcloud-template
springcloud-template
└── template-auth
└── authentication
└── LoginService -- 登录抽象定义
└── AppWeixinService -- APP微信授权登录
└── LocalMobileService -- 本机号码一键登录
└── MobileCodeBindService -- 手机号 验证码登录并绑定授权码
└── MobileCodeService -- 手机号 验证码登录
└── UsernamePasswordService -- 用户名 密码登录
└── WeixinMiniappService -- 微信小程序登录
└── WeixinMpService -- 微信公众号登录
└── LoginType -- 多种登录方式定义
└── controller
└── AccountController -- 登录API
└── token
└── TokenService -- token抽象定义
└── template-framework-edge
└── interceptor
└── AccessControlConfigurer
└── AccessControlInterceptor -- 根据header有无用户ID拦截需登录API
└── template-zuul或template-gateway
└── filter
└── TokenFilter -- 解析token获取用户ID并将设置到header