验证码与登录过程逻辑学习总结
目录
前言
一、验证码与登录
二、使用步骤
1.先apipost测试一波
2.先搞验证码
3.跨域问题
4.后端走起
总结
前言
近期要做一个比较完整的demo,需要自己做一个前端登录页面,不过api接口都是现成的,一开始以为过程会很easy,但是由于跨域问题、后端代理、验证码关联登问题,还是小小折腾一些,正好将过程记录下。
一、验证码与登录
现代网站为了系统的安全性以及降低恶意攻击,一般都会在用户名、密码验证的基础上,增加验证码验证。
这里主要就涉及验证码关联问题,即怎么让后端知道后端生成的验证码就是对应我前端输入的验证码?以下我们就来一步步讲解。包括验证码、cookie、登录逻辑登
二、使用步骤
1.先apipost测试一波
通过apipost先把涉及的两个接口调用通了,然后再写代码。
测试发现,调用这两个接口的时候,都给传递同一个cookie即可成功登录。
那么,我写代码的时候,也生成一个cookie,给这两个接口传递同一个cookie应该就可以了。
2.先搞验证码
<div class="mb-6"><label for="captcha" class="block text-gray-700 text-sm font-bold mb-2">验证码</label><div class="flex gap-2"><input type="text" id="captcha" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" required><img id="captchaImage" alt="验证码" class="h-10 cursor-pointer" onclick="refreshCaptcha()"></div>
</div><script>// 刷新验证码async function refreshCaptcha() {const captchaImage = document.getElementById('captchaImage');const url = `http://xx.com/api/captcha?t=${Date.now()}`;captchaImage.src = url;}// 页面加载时刷新验证码window.onload = refreshCaptcha;</script>
3.跨域问题
由于原有接口的安全性设置,进行了CORS跨域设置,导致前端无法直接请求。
另外,出于安全考虑,前端也无法手动给后端传递cookie,正常过程是后端给前端返回cookie,然后后续调用后端接口会自动传递当前域下的cookie。
这里通过apipost工具、后端写代码都没问题,主要是对浏览器请求做了限制,准确说是浏览器的一种安全机制。
在不能调整原有接口的CORS设置的情况,那就只能自己写后端代理接口,那么关键就是让后端可以成功调用,那么问题基本就解决了。
4.后端走起
后端实现生成验证码是很顺利,但是在登录逻辑这里发现前面说的“给这两个接口传递相同的cookie”的假设无法成功登录。
再次F12看原系统登录请求,发现获取验证码的接口会返回cookie,然后登录的时候传递了这个cookie。之前一直没注意到,是当前问AI的时候,AI跟我说的是获取验证码会通过Set_Cookie返回cookie,实际直接就是cookie,而且还不是每次请求都会返回,可能本地有了就不返回?
按照最新思路,重新调整逻辑:
1)获取验证码,获取到cookie;设置到前端
2)登录逻辑,自动传递到后端,后端再把这个cookie传递给实际登录接口。
ok搞定。
@app.get("/captcha")
async def get_captcha(request: Request):target_url = f"{KAPTCHA_URL}?t={int(time.time()*1000)}"try:resp = requests.get(target_url, stream=True)cookie_val= resp.cookies["cookie_key"]response = StreamingResponse(resp.iter_content(chunk_size=64), media_type=resp.headers["Content-Type"])# 开发环境临时禁用Secureresponse.set_cookie(key="cookie_key",value=cookie_val,httponly=True,samesite="Lax", # 开发环境使用Laxsecure=False, # 开发环境禁用Securepath="/",)return responseexcept Exception as e:return JSONResponse(content={"error": str(e)}, status_code=500)@app.post("/user/login")
async def proxy_login(request: Request):# 获取 form-dataform_data = await request.form()# 单独获取某个字段login_id = form_data.get("loginId")password = form_data.get("password")kaptcha_code = form_data.get("kaptchaCode")cookies = request.cookiescookie_val = cookies.get("cookie_key")try:response = login(login_id, password, kaptcha_code, cookie_val)return JSONResponse(content=response.json(), status_code=response.status_code)except requests.RequestException as e:return JSONResponse(content={"errCode": ErrCode.FAILURE.value,"errMsg": str(e),"data": {}},status_code=500,)
总结
以上就是今天要讲的内容,本文主要介绍了自己写前端集成已有验证码、登录接口过程中遇到的问题以及如何解决,希望可以帮助到大家。
本文重点总结:
1)前端安全性考虑,前端无法跨域访问后端接口,无法直接给后端传递cookie。调用后端接口的时候,会默认把当前域下cookie传递到后端
2)验证码与登录逻辑,验证码接口会返回一个cookie,调用登录接口的时候传递这个cookie,实现前后端同一个验证码的关联验证