WX点击小程序的时候,会获取到一个code,将code参数发送给服务器端,可以获取到用户的openid信息
KaTeX parse error: Expected 'EOF', got '&' at position 64: …ion?appid=appid&̲secret=secrer&j…code.‘&grant_type=authorization_code’;
然后远程请求,可以获取到下面一串这样的含有openid的json字符串{“session_key”:“fvfrPGXOquGmfddsfsdf==”,“openid”:“o54q768tKkaeeee60M”}
拿到openid后,不能直接返回给前端,需要进行对称加密或者存一份token,返回给请求端。
PS:为什么不能直接返回openid信息给前端,第一出于安全考虑造成openid直接泄露,第二,如果用户用该openid试图绑定系统里面的用户,该openid无法验证身份,必须再次去远程服务器端进行一次多余的请求,如果不验证openid,则会出现任意字符串可绑定系统里面手机号情况。第三种情况,如果是需要用户凭借openid登录,不绑定身份情况下就注册一个账号,这个时候,直接使用openid生成身份就会被随意注册用户。所以返回给前端的openid一定是需要经过加密或者经过转换的token,也可以是服务器上生成的一个随机token,然后使用cache方式存储,然后通过去读cache值的方式获取openid。这样外部攻击者无法伪造token,openid是受保护的,所以正常验证。
返回给前端之后,后端此时可以生成一个用户登录记录(也就是没有用户名和手机号,只有一个openid和注册时间的相关账号),等前端用户注册的时候,再来真正填写东西(如果业务需要查看全部点击过的用户,这就需要把username和登录号码设置成不唯一),这个改动代价比较大,一般Mysql里面我们设置username的unique唯一性,确保快速查询到用户,不是业务强制性需求,我们都不会记录只点击过小程序的用户。所以一般我们采用第二种方法,就是用户注册的时候,额外传递这个token,token合法通过,我们对注册用户和这个openid进行绑定。当然也可以是用户主动发起绑定,都是核心需要这个token。
小程序授权登录的开发
免登录的逻辑是用户发送获取到的code的时候,因为服务器端已经拿到了openid,根据openid直接查询数据库,检查用户是否存在,如果存在,可以凭借openid 直接读取自己服务器的数据。这样就实现了免登录效果。
所以为了避免openid伪造的风险,我们需要对返回给前端的openid进行数据加密,数据回到后台后,再对我们发出去的数据进行解密核对。
账号相关绑定: (绑定逻辑相对比较复杂,非常多的if/else相关逻辑,绑定的逻辑普遍性的比较复杂)
直接相关的绑定就是openid检查是否存在绑定过其他账号(否则会覆盖现有的绑定)
也要检查手机号是否被绑定过(提示手机号已经绑定了 )
然后提交openid+mobile 就可以让俩者采用最简单的写入表方式绑定。
要将openid和mobile 进行分开检查
检查openid 检查是否存在,存在的情况下需要检查号码是否存在(如果不记录没有手机号码的用户,有openid一定会有手机号),如果没有号码就可以继续绑定,可以继续绑定,否则退出。
检查mobile是否存在,是否绑定过,绑定过不再给予绑定,未绑定,更新此次绑定信息,然后免登录。
最后是将用户简单注册,注册成功后,自动登录状态。
拓展:
理解unionid
openid
是用户在特定的微信公众号、小程序等应用下的唯一标识。一旦生成,通常会保持稳定
unionid 如果一个用户同时使用多个微信应用(如公众号、小程序、移动应用等),且这些应用都绑定到同一个微信开放平台账号下,那么这个用户在这些应用中的唯一标识就是unionid
通过unionid我们就可以识别出用户在我们各个体系里面唯一的身份,因为每个平台的openid不一样,导致我们无法识别用户身份,而要识别我们整个开放平台,需要unionid 应用场景,比如一个公司注册了几十个公众号和小程序账号,每个账号看着可能好几万人,上百万粉丝,但是通过unionid我们会发现其实就十几万,其他的都是反复注册在推广,这样也就能很清楚的看到活跃用户相关信息。
通常unionid会在给openid的时候,一起返回给我们。