在django中使用Redis存取session

一.Redis的配置

1.django的缓存配置

# redis在django中的配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # "PASSWORD": "123",
        }
    }
}

2.django中session的配置

# session的存储配置
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'

# 设置session失效时间,单位为秒
SESSION_COOKIE_AGE = 60*5

配置完这个2个后,在视图中再设置session,就会自动将session保存在Redis中

二.路由

from django.conf.urls import url
from django.contrib import admin
from api import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^session/$',views.SetSession.as_view() ),
]

三.视图

这里视图使用的是MBV,还用了restframework

from rest_framework.views import APIView
# Create your views here.
from rest_framework.response import Response
from api import models


class MyResponse():
    def __init__(self):
        self.status=100
        self.msg=None

    @property
    def get_dic(self):
        return self.__dict__


class SetSession(APIView):
    # 设置session,直接request.session就自动把session值保存到Redis中了
    def post(self,request):
        response = MyResponse()
        request.session["username"]="django"
        request.session["verify_code"]="123"
        response.msg="保存session成功"
        return Response(response.get_dic)

    # 获取session,直接从request.session中取session的值
    def get(self,request):
        response = MyResponse()
        username_redis=request.session.get("username")
        verify_code_redis=request.session.get("verify_code")
        print(username_redis,verify_code_redis)
        if username_redis=="django" and verify_code_redis=="123":
            response.msg="验证成功"
            return Response(response.get_dic)
        response.msg="验证失败"
        response.status=101
        return Response(response.get_dic)

四.浏览器发送请求

这里使用了postman

设置session用了post请求

获取session用了get请求

 

五.cache组件存取token

需要联合restframework认证组件一起使用

1.先创建一个认证类

from rest_framework.authentication import BaseAuthentication
from django.core.cache import cache
from api import models
from rest_framework.exceptions import AuthenticationFailed


class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        token=request.GEt.get("token")
        # 从Redis中取出token,前提是已经在settings中配置Redis
        user=cache.get(token)
        if user:
            return user,token
        token = models.Token.objects.filter(key=token).first()
        if token:
            return token.user,token
        else:
            raise AuthenticationFailed("你没有登入")

2.使用APIView写登入接口

from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from django.core.exceptions import ObjectDoesNotExist
from uuid import uuid4
from django.core.cache import cache

class MyResponse():
    def __init__(self):
        self.status=100
        self.msg=None

    @property
    def get_dic(self):
        return self.__dict__

class Login(APIView):
    def post(self,request):
        response = MyResponse()
        name=request.data.get("name")
        pwd=request.data.get("pwd")
        try:
            user=models.UserInfo.objects.filter(username=name,password=pwd).first()
        except ObjectDoesNotExist as e:
            response.msg = "没有查收到"
            response.status = 101
            return Response(response.get_dic)
        if user:
            token=uuid4()
            try:
                models.Token.objects.update_or_create(user=user,defaults={'key':token})
                # 将token存到Redis中,设置超时时间一天
                cache.set(token, user, 60 * 60 * 24)
                response.msg = '登录成功'
                response.token = token
                response.name = name
            except ObjectDoesNotExist as e:
                response.msg = "没有查收到"
                response.status = 101
                return Response(response.get_dic)
        else:
            response.msg = '用户名或密码错误'
            response.status = 101

        return Response(response.get_dic)

3.最后只要配置需要加登入需求的接口

局部配置:放在视图函数中

authentication_classes=[LoginAuth]

全局配置:settings中

REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":["导入你写的认证类",]
}

 

posted @ 2019-02-28 17:11  Maple_feng  阅读(3631)  评论(0编辑  收藏  举报