通过 cookie headers 发送令牌认证信息安全吗?
Is sending token authentication information via cookie headers secure?
0
我绝不是一名安全工程师,而且我才刚刚开始我作为 Web 开发人员的旅程。我在后端使用称为 django 的 python 包,在前端使用 react.js。最近我加入了 django-channels ,这是一个让我能够在我的项目中使用 websockets 的包。由于我已经分离了我的前端和后端,我使用的身份验证基础是通过令牌(将考虑使用 jwt)。
问题是 javascript 无法通过 websocket 连接发送身份验证 headers(或者我告诉过的),因此很多人使用 cookie 来发送此身份验证代币代替。这是我如何从前端发送令牌的示例片段:
const path = wsStart + 'localhost:8000'+ loc.pathname
document.cookie = 'authorization=' + token + ';'
this.socketRef = new WebSocket(path)
这样做可以让我通过在后端使用自定义中间件来提取令牌信息。
import re
from channels.db import database_sync_to_async
from django.db import close_old_connections
@database_sync_to_async
def get_user(token_key):
try:
return Token.objects.get(key=token_key).user
except Token.DoesNotExist:
return AnonymousUser()
class TokenAuthMiddleware:
"""
Token authorization middleware for Django Channels 2
see:
https://channels.readthedocs.io/en/latest/topics/authentication.html#custom-authentication
"""
def __init__(self, inner):
self.inner = inner
def __call__(self, scope):
return TokenAuthMiddlewareInstance(scope, self)
class TokenAuthMiddlewareInstance:
def __init__(self, scope, middleware):
self.middleware = middleware
self.scope = dict(scope)
self.inner = self.middleware.inner
async def __call__(self, receive, send):
close_old_connections()
headers = dict(self.scope["headers"])
print(headers[b"cookie"])
if b"authorization" in headers[b"cookie"]:
print('still good here')
cookies = headers[b"cookie"].decode()
token_key = re.search("authorization=(.*)(; )?", cookies).group(1)
if token_key:
self.scope["user"] = await get_user(token_key)
inner = self.inner(self.scope)
return await inner(receive, send)
TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))
然而,这引发了某种形式的安全危险信号(或者我告诉过的)。
因此我希望将这个问题扩展到那里的安全退伍军人:
- 这种通过 cookie 发送令牌认证信息的方法 headers 安全吗?
- 我执行这个方法安全吗?
- 有没有办法进一步保护它?
- 如果您使用的是 HTTPS (WSS) websocket 连接,那么大多数情况下。
- 是的,看起来不错
- 是的,有更好的方法。
如果您可以设置(正常的)django 会话 cookie,则创建一个常规的 HTTP 端点(在此域名上),这通常是您的 django 登录端点。这将设置一个 HTTPONLY 的 cookie(也就是无法从 javascript 读取)。这很重要,这样您可能在页面上使用的任何其他 js 代码都无法读取并窃取该值。
然后就可以使用https://channels.readthedocs.io/en/latest/topics/sessions.html.
请注意,当 运行 在生产过程中(仅使用 HTTPs)时,您也应该在 django 设置中设置 SESSION_COOKIE_SECURE=True
。
0
我绝不是一名安全工程师,而且我才刚刚开始我作为 Web 开发人员的旅程。我在后端使用称为 django 的 python 包,在前端使用 react.js。最近我加入了 django-channels ,这是一个让我能够在我的项目中使用 websockets 的包。由于我已经分离了我的前端和后端,我使用的身份验证基础是通过令牌(将考虑使用 jwt)。
问题是 javascript 无法通过 websocket 连接发送身份验证 headers(或者我告诉过的),因此很多人使用 cookie 来发送此身份验证代币代替。这是我如何从前端发送令牌的示例片段:
const path = wsStart + 'localhost:8000'+ loc.pathname
document.cookie = 'authorization=' + token + ';'
this.socketRef = new WebSocket(path)
这样做可以让我通过在后端使用自定义中间件来提取令牌信息。
import re
from channels.db import database_sync_to_async
from django.db import close_old_connections
@database_sync_to_async
def get_user(token_key):
try:
return Token.objects.get(key=token_key).user
except Token.DoesNotExist:
return AnonymousUser()
class TokenAuthMiddleware:
"""
Token authorization middleware for Django Channels 2
see:
https://channels.readthedocs.io/en/latest/topics/authentication.html#custom-authentication
"""
def __init__(self, inner):
self.inner = inner
def __call__(self, scope):
return TokenAuthMiddlewareInstance(scope, self)
class TokenAuthMiddlewareInstance:
def __init__(self, scope, middleware):
self.middleware = middleware
self.scope = dict(scope)
self.inner = self.middleware.inner
async def __call__(self, receive, send):
close_old_connections()
headers = dict(self.scope["headers"])
print(headers[b"cookie"])
if b"authorization" in headers[b"cookie"]:
print('still good here')
cookies = headers[b"cookie"].decode()
token_key = re.search("authorization=(.*)(; )?", cookies).group(1)
if token_key:
self.scope["user"] = await get_user(token_key)
inner = self.inner(self.scope)
return await inner(receive, send)
TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))
然而,这引发了某种形式的安全危险信号(或者我告诉过的)。
因此我希望将这个问题扩展到那里的安全退伍军人:
- 这种通过 cookie 发送令牌认证信息的方法 headers 安全吗?
- 我执行这个方法安全吗?
- 有没有办法进一步保护它?
- 如果您使用的是 HTTPS (WSS) websocket 连接,那么大多数情况下。
- 是的,看起来不错
- 是的,有更好的方法。
如果您可以设置(正常的)django 会话 cookie,则创建一个常规的 HTTP 端点(在此域名上),这通常是您的 django 登录端点。这将设置一个 HTTPONLY 的 cookie(也就是无法从 javascript 读取)。这很重要,这样您可能在页面上使用的任何其他 js 代码都无法读取并窃取该值。
然后就可以使用https://channels.readthedocs.io/en/latest/topics/sessions.html.
请注意,当 运行 在生产过程中(仅使用 HTTPs)时,您也应该在 django 设置中设置 SESSION_COOKIE_SECURE=True
。