이 글은 주로 Python을 사용하여 웹 사용자 로그인 및 등록 기능을 구현하는 튜토리얼을 소개합니다. 필요한 친구는 이를 참고할 수 있습니다.
사용자 관리는 대부분의 웹 사이트가 해결해야 할 문제입니다. 사용자 관리에는 사용자 등록 및 로그인이 포함됩니다.
사용자 등록은 비교적 간단합니다. 먼저 API를 통해 사용자 등록 기능을 구현할 수 있습니다.
_RE_MD5 = re.compile(r'^[0-9a-f]{32}$') @api @post('/api/users') def register_user(): i = ctx.request.input(name='', email='', password='') name = i.name.strip() email = i.email.strip().lower() password = i.password if not name: raise APIValueError('name') if not email or not _RE_EMAIL.match(email): raise APIValueError('email') if not password or not _RE_MD5.match(password): raise APIValueError('password') user = User.find_first('where email=?', email) if user: raise APIError('register:failed', 'email', 'Email is already in use.') user = User(name=name, email=email, password=password, image='http://www.gravatar.com/avatar/%s?d=mm&s=120' % hashlib.md5(email).hexdigest()) user.insert() return user
사용자 비밀번호는 MD5 계산 후 클라이언트가 전달한 32비트 해시 문자열이므로 서버는 사용자의 원래 비밀번호를 알 수 없습니다.
다음으로 등록 페이지를 만들고 사용자가 등록 양식을 작성할 수 있도록 한 다음 등록된 사용자의 API에 데이터를 제출할 수 있습니다.
{% extends '__base__.html' %} {% block title %}注册{% endblock %} {% block beforehead %} <script> function check_form() { $('#password').val(CryptoJS.MD5($('#password1').val()).toString()); return true; } </script> {% endblock %} {% block content %} <p class="uk-width-2-3"> <h1>欢迎注册!</h1> <form id="form-register" class="uk-form uk-form-stacked" onsubmit="return check_form()"> <p class="uk-alert uk-alert-danger uk-hidden"></p> <p class="uk-form-row"> <label class="uk-form-label">名字:</label> <p class="uk-form-controls"> <input name="name" type="text" class="uk-width-1-1"> </p> </p> <p class="uk-form-row"> <label class="uk-form-label">电子邮件:</label> <p class="uk-form-controls"> <input name="email" type="text" class="uk-width-1-1"> </p> </p> <p class="uk-form-row"> <label class="uk-form-label">输入口令:</label> <p class="uk-form-controls"> <input id="password1" type="password" class="uk-width-1-1"> <input id="password" name="password" type="hidden"> </p> </p> <p class="uk-form-row"> <label class="uk-form-label">重复口令:</label> <p class="uk-form-controls"> <input name="password2" type="password" maxlength="50" placeholder="重复口令" class="uk-width-1-1"> </p> </p> <p class="uk-form-row"> <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-user"></i> 注册</button> </p> </form> </p> {% endblock %} Try
이렇게 하면 사용자 등록 기능이 완료되었습니다.
사용자 로그인은 사용자 등록보다 복잡합니다. HTTP 프로토콜은 상태 비저장 프로토콜이고 서버가 사용자 상태를 추적하려고 하기 때문에 이는 쿠키를 통해서만 달성할 수 있습니다. 대부분의 웹 프레임워크는 사용자 상태를 저장하는 쿠키를 캡슐화하는 세션 기능을 제공합니다.
Session의 장점은 간단하고 사용하기 쉽다는 점과 사용자 로그인 정보를 Session에서 직접 검색할 수 있다는 것입니다.
Session의 단점은 사용자 로그인 정보를 저장하기 위해 서버가 메모리에 매핑 테이블을 유지해야 한다는 것입니다. 서버가 2개 이상인 경우 Session을 클러스터링해야 하므로 Session을 사용하는 Web App은 확장하기 어렵습니다.
우리는 사용자 로그인을 확인하기 위해 쿠키를 직접 읽는 방법을 사용합니다. 이 방법의 장점은 서버가 모든 URL을 상태 비저장 방식으로 처리하고 확인할 수 있다는 것입니다. 여러 서버로 확장되었습니다.
서버는 로그인 성공 후 쿠키를 생성하여 브라우저에 전송하므로 이 쿠키가 클라이언트에 의해 위조되지 않도록 해야 합니다.
위조 방지 쿠키를 구현하는 핵심은 단방향 알고리즘(예: MD5)을 사용하는 것입니다. 예:
사용자가 올바른 비밀번호를 입력하여 성공적으로 로그인하면 서버는 데이터베이스에서 사용자의 ID를 가져올 수 있습니다. 문자열로 출력:
"User ID" + "Expiration Time" + MD5("User ID" + "User Password" + "Expiration Time" + "SecretKey")
브라우저가 쿠키를 보낼 때 서버가 얻을 수 있는 정보는 다음과 같습니다.
사용자 ID
만료 시간
MD5 값
만료 시간에 도달하지 않은 경우 서버는 사용자 비밀번호를 검색합니다. 사용자 ID를 기준으로 다음과 같이 계산합니다.
MD5("사용자 ID" + "사용자 비밀번호" + "만료 시간" + "비밀 키")
브라우저 쿠키의 MD5와 비교하면 동일한 것입니다. 사용자가 로그인했음을 의미합니다. 그렇지 않으면 쿠키가 위조됩니다.
이 알고리즘의 핵심은 MD5가 단방향 알고리즘이라는 것입니다. 즉, 원래 문자열에서 MD5를 계산할 수 있지만 MD5에서 원래 문자열을 추론할 수는 없습니다.
그래서 로그인 API는 다음과 같이 구현할 수 있습니다.
@api @post('/api/authenticate') def authenticate(): i = ctx.request.input() email = i.email.strip().lower() password = i.password user = User.find_first('where email=?', email) if user is None: raise APIError('auth:failed', 'email', 'Invalid email.') elif user.password != password: raise APIError('auth:failed', 'password', 'Invalid password.') max_age = 604800 cookie = make_signed_cookie(user.id, user.password, max_age) ctx.response.set_cookie(_COOKIE_NAME, cookie, max_age=max_age) user.password = '******' return user # 计算加密cookie: def make_signed_cookie(id, password, max_age): expires = str(int(time.time() + max_age)) L = [id, expires, hashlib.md5('%s-%s-%s-%s' % (id, password, expires, _COOKIE_KEY)).hexdigest()] return '-'.join(L) 对于每个URL处理函数,如果我们都去写解析cookie的代码,那会导致代码重复很多次。 利用拦截器在处理URL之前,把cookie解析出来,并将登录用户绑定到ctx.request对象上,这样,后续的URL处理函数就可以直接拿到登录用户: @interceptor('/') def user_interceptor(next): user = None cookie = ctx.request.cookies.get(_COOKIE_NAME) if cookie: user = parse_signed_cookie(cookie) ctx.request.user = user return next() # 解密cookie: def parse_signed_cookie(cookie_str): try: L = cookie_str.split('-') if len(L) != 3: return None id, expires, md5 = L if int(expires) < time.time(): return None user = User.get(id) if user is None: return None if md5 != hashlib.md5('%s-%s-%s-%s' % (id, user.password, expires, _COOKIE_KEY)).hexdigest(): return None return user except: return None Try
이렇게 해서 사용자 등록 및 로그인 기능이 완성되었습니다.
관련 권장사항:
위 내용은 Python을 사용하여 웹 사용자 로그인 및 등록 기능 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!