add redis cache and fix logout bugs

storage_cloud
nineven 5 years ago
parent 33f26558ea
commit 5e84a2711e
  1. 27
      fir_client/src/components/FirHeader.vue
  2. 2
      fir_client/src/restful/index.js
  3. 35
      fir_ser/api/migrations/0016_auto_20200327_1121.py
  4. 2
      fir_ser/api/models.py
  5. 32
      fir_ser/api/utils/TokenManager.py
  6. 50
      fir_ser/api/utils/auth.py
  7. 20
      fir_ser/api/views/login.py
  8. 5
      fir_ser/api/views/logout.py
  9. 9
      fir_ser/fir_ser/settings.py

@ -41,7 +41,7 @@
</template> </template>
<script> <script>
import {logout} from '../restful'
export default { export default {
name: "FirHeader", name: "FirHeader",
data() { data() {
@ -62,21 +62,24 @@
} else if (command === 'chpasswd') { } else if (command === 'chpasswd') {
this.$router.push({name: 'FirUserProfileChangePwd'}) this.$router.push({name: 'FirUserProfileChangePwd'})
}else if(command === 'exit'){ }else if(command === 'exit'){
this.$cookies.remove("token"); logout(data => {
this.$cookies.remove("auth_token"); if (data.code === 1000) {
this.$cookies.remove("username"); this.$message.success("退出成功");
this.$cookies.remove("first_name"); this.$cookies.remove("token");
this.$store.dispatch('doucurrentapp', {}); this.$cookies.remove("auth_token");
this.$store.dispatch('getUser', {}); this.$cookies.remove("username");
this.$router.push({name: 'FirLogin'}); this.$cookies.remove("first_name");
this.$store.dispatch('doucurrentapp', {});
this.$store.dispatch('getUser', {});
this.$router.push({name: 'FirLogin'});
} else {
this.$message.error("退出失败")
}
}, {})
} }
} }
}, created() { }, created() {
// this.$bus.$on('appName',val =>{
// this.appName = val;
// alert('header')
// })
this.appName = this.$route.params.id this.appName = this.$route.params.id
}, watch: { }, watch: {
$route: function () { $route: function () {

@ -419,7 +419,7 @@ export function loginFun(callBack, params, load = true) {
/**用户退出 */ /**用户退出 */
export function logout(callBack, params, load = true) { export function logout(callBack, params, load = true) {
getData( getData(
false, 'DELETE',
USERSEVER + '/logout', USERSEVER + '/logout',
params, params,
data => { data => {

@ -0,0 +1,35 @@
# Generated by Django 3.0.3 on 2020-03-27 03:21
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('api', '0015_auto_20200326_1454'),
]
operations = [
migrations.AlterField(
model_name='appstorage',
name='additionalparameters',
field=models.TextField(blank=True, help_text='阿里云:{"sts_role_arn":"arn信息","endpoint":""} 七牛云:{"domain_name":""} 本地存储:{"domain_name":""}', max_length=256, null=True, verbose_name='额外参数'),
),
migrations.AlterField(
model_name='token',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auth_token', to=settings.AUTH_USER_MODEL, verbose_name='关联用户'),
),
migrations.AlterField(
model_name='userinfo',
name='is_active',
field=models.BooleanField(default=True, verbose_name='账户状态,默认启用'),
),
migrations.AlterField(
model_name='userinfo',
name='storage',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='app_storage', to='api.AppStorage', verbose_name='存储'),
),
]

@ -60,7 +60,7 @@ class Token(models.Model):
The default authorization token model. The default authorization token model.
""" """
access_token = models.CharField(max_length=42, unique=True) access_token = models.CharField(max_length=42, unique=True)
user = models.OneToOneField( user = models.ForeignKey(
UserInfo, related_name='auth_token', UserInfo, related_name='auth_token',
on_delete=models.CASCADE, verbose_name="关联用户" on_delete=models.CASCADE, verbose_name="关联用户"
) )

@ -8,10 +8,42 @@ import string
import random import random
import time import time
from threading import Thread from threading import Thread
from django.core.cache import cache
'''
user = cache.get(token)
delta = datetime.timedelta(weeks=2) - delta
cache.set(token_obj.key, token_obj.user, min(delta.total_seconds(), 3600 * 24 * 7))
'''
class DownloadToken(object): class DownloadToken(object):
def make_token(self,release_id,time_limit=60):
random_str = uuid.uuid1().__str__().split("-")[0:-1]
user_ran_str = uuid.uuid5(uuid.NAMESPACE_DNS, release_id).__str__().split("-")
user_ran_str.extend(random_str)
new_str = "".join(user_ran_str)
cache.set(new_str, {
"atime":time.time()+time_limit,
"data":release_id
}, time_limit)
return new_str
def verify_token(self,token,release_id):
try:
values = cache.get(token)
if release_id in values.get("data",None):
return True
except Exception as e:
print(e)
return False
return False
class DownloadTokenLocal(object):
TokenLists = [] TokenLists = []
flag={'stat':1} flag={'stat':1}

@ -10,39 +10,6 @@ import pytz
import base64 import base64
class ExpiringTokenAuthentication(BaseAuthentication): class ExpiringTokenAuthentication(BaseAuthentication):
def authenticate1(self, request):
'''
1 对token设置14天有效时间
2 缓存存储
:param request:
:return:
'''
if request.method == "OPTIONS":
return None
token = request.META.get("HTTP_AUTHORIZATION")
# 1 校验是否存在token字符串
# 1.1 缓存校验
user = cache.get(token)
if user:
print("缓存校验成功")
return user, token
# 1.2 数据库校验
token_obj = Token.objects.filter(key=token).first()
if not token_obj:
raise AuthenticationFailed("认证失败!")
# 2 校验是否在有效期内
now = datetime.datetime.now() # 2018-1-12- 0 0 0
delta = now - token_obj.created
state = delta < datetime.timedelta(weeks=2)
if state:
# 校验成功,写入缓存中
delta = datetime.timedelta(weeks=2) - delta
cache.set(token_obj.key, token_obj.user, min(delta.total_seconds(), 3600 * 24 * 7))
print("数据库校验成功")
return token_obj.user, token_obj.key
else:
raise AuthenticationFailed("认证超时!")
def authenticate(self, request): def authenticate(self, request):
if request.method == "OPTIONS": if request.method == "OPTIONS":
@ -58,13 +25,20 @@ class ExpiringTokenAuthentication(BaseAuthentication):
if not auth_token: if not auth_token:
raise AuthenticationFailed({"code": 1001, "error": "缺少token"}) raise AuthenticationFailed({"code": 1001, "error": "缺少token"})
token_obj = Token.objects.filter(access_token=auth_token).first()
if not token_obj: cacheuserinfo = cache.get(auth_token)
if not cacheuserinfo:
raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) raise AuthenticationFailed({"code": 1001, "error": "无效的token"})
if user_name != token_obj.user.username: if user_name != cacheuserinfo.get('username',None):
raise AuthenticationFailed({"code": 1001, "error": "token校验失败"}) raise AuthenticationFailed({"code": 1001, "error": "token校验失败"})
if token_obj.user.is_active:
return token_obj.user, token_obj user_obj = UserInfo.objects.filter(uid=cacheuserinfo.get('uid',None),username=cacheuserinfo.get("username")).first()
# token_obj = Token.objects.filter(access_token=auth_token).first()
if not user_obj:
raise AuthenticationFailed({"code": 1001, "error": "无效的token"})
if user_obj.is_active:
cache.set(auth_token, cacheuserinfo, 3600 * 24 * 7)
return user_obj,auth_token
else: else:
raise AuthenticationFailed({"code": 1001, "error": "用户被禁用"}) raise AuthenticationFailed({"code": 1001, "error": "用户被禁用"})

@ -2,25 +2,21 @@ from django.contrib import auth
from api.models import Token, UserInfo from api.models import Token, UserInfo
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.serializer import UserInfoSerializer from api.utils.serializer import UserInfoSerializer
from api.utils.app.randomstrings import make_from_user_uuid from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
from fir_ser import settings
import binascii import binascii
import os,datetime import os,datetime
from api.utils.TokenManager import DownloadToken,generateNumericTokenOfLength from api.utils.TokenManager import DownloadToken,generateNumericTokenOfLength
from api.utils.auth import ExpiringTokenAuthentication from api.utils.auth import ExpiringTokenAuthentication
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from django.middleware import csrf from django.middleware import csrf
from api.utils.storage.storage import Storage
def get_token(request): def get_token(request):
token = csrf.get_token(request) token = csrf.get_token(request)
return {'csrf_token': token} return {'csrf_token': token}
class LoginView(APIView): class LoginView(APIView):
def generate_key(self): def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode() return binascii.hexlify(os.urandom(32)).decode()
def post(self, request): def post(self, request):
response = BaseResponse() response = BaseResponse()
@ -41,12 +37,13 @@ class LoginView(APIView):
# update the token # update the token
key = self.generate_key() key = self.generate_key()
now = datetime.datetime.now() now = datetime.datetime.now()
Token.objects.update_or_create(user=user, defaults={"access_token": key, "created": now})
user_info = UserInfo.objects.get(pk=user.pk) user_info = UserInfo.objects.get(pk=user.pk)
cache.set(key,{'uid':user_info.uid,'username':user_info.username},3600*24*7)
Token.objects.create(user=user, **{"access_token": key, "created": now})
serializer = UserInfoSerializer(user_info,) serializer = UserInfoSerializer(user_info,)
data = serializer.data data = serializer.data
response.msg = "验证成功!" response.msg = "验证成功!"
response.userinfo = data response.userinfo = data
response.token = key response.token = key
@ -105,6 +102,13 @@ class UserInfoView(APIView):
user.set_password(surepassword) user.set_password(surepassword)
user.save() user.save()
res.msg="密码修改成功" res.msg="密码修改成功"
auth_token = request.auth
for token_obj in Token.objects.filter(user=user):
if token_obj.access_token != auth_token:
cache.delete(token_obj.access_token)
token_obj.delete()
return Response(res.dict) return Response(res.dict)
else: else:
res.code = 1004 res.code = 1004

@ -1,6 +1,7 @@
from rest_framework.views import APIView from rest_framework.views import APIView
from api.utils.auth import ExpiringTokenAuthentication from api.utils.auth import ExpiringTokenAuthentication
from api.models import Token from api.models import Token
from django.core.cache import cache
from rest_framework.response import Response from rest_framework.response import Response
from api.utils.permission import LoginUserPermission from api.utils.permission import LoginUserPermission
@ -12,5 +13,7 @@ class LogoutView(APIView):
def delete(self, request): def delete(self, request):
user = request.user.pk user = request.user.pk
Token.objects.filter(user=user).delete() auth_token = request.auth
cache.delete(auth_token)
Token.objects.filter(user=user,access_token=auth_token).delete()
return Response({"code": 1000}) return Response({"code": 1000})

@ -143,17 +143,16 @@ GEE_TEST = {
], # 不用验证的用户(存放着用户的uid) ], # 不用验证的用户(存放着用户的uid)
} }
SHOPPING_CAR_KEY = "shopping_car_%s_%s"
ACCOUNT_KEY = "account_%s_%s"
CACHES1 = {
CACHES = {
"default": { "default": {
"BACKEND": "django_redis.cache.RedisCache", "BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379", "LOCATION": "redis://192.168.137.130:6379",
"OPTIONS": { "OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient", "CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}, "CONNECTION_POOL_KWARGS": {"max_connections": 100},
# "PASSWORD": "密码", "PASSWORD": "nineven",
"DECODE_RESPONSES":True "DECODE_RESPONSES":True
} }
}, },

Loading…
Cancel
Save