mirror of https://github.com/openspug/spug
U improve security
parent
4795c9e9ae
commit
3e09794b06
|
@ -5,9 +5,11 @@ from django.core.cache import cache
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from libs import JsonParser, Argument, human_datetime, json_response
|
from libs import JsonParser, Argument, human_datetime, json_response
|
||||||
|
from libs.utils import get_request_real_ip
|
||||||
from apps.account.models import User, Role
|
from apps.account.models import User, Role
|
||||||
from apps.setting.models import Setting
|
from apps.setting.models import Setting
|
||||||
from libs.ldap import LDAP
|
from libs.ldap import LDAP
|
||||||
|
import ipaddress
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
|
@ -155,7 +157,7 @@ def login(request):
|
||||||
Argument('type', required=False)
|
Argument('type', required=False)
|
||||||
).parse(request.body)
|
).parse(request.body)
|
||||||
if error is None:
|
if error is None:
|
||||||
x_real_ip = request.headers.get('x-real-ip', '')
|
x_real_ip = get_request_real_ip(request.headers)
|
||||||
user = User.objects.filter(username=form.username, type=form.type).first()
|
user = User.objects.filter(username=form.username, type=form.type).first()
|
||||||
if user and not user.is_active:
|
if user and not user.is_active:
|
||||||
return json_response(error="账户已被系统禁用")
|
return json_response(error="账户已被系统禁用")
|
||||||
|
@ -198,7 +200,7 @@ def handle_user_info(user, x_real_ip):
|
||||||
'access_token': user.access_token,
|
'access_token': user.access_token,
|
||||||
'nickname': user.nickname,
|
'nickname': user.nickname,
|
||||||
'is_supper': user.is_supper,
|
'is_supper': user.is_supper,
|
||||||
'has_real_ip': True if x_real_ip else False,
|
'has_real_ip': x_real_ip and ipaddress.ip_address(x_real_ip).is_global,
|
||||||
'host_perms': [] if user.is_supper else user.host_perms,
|
'host_perms': [] if user.is_supper else user.host_perms,
|
||||||
'permissions': [] if user.is_supper else user.page_perms
|
'permissions': [] if user.is_supper else user.page_perms
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Released under the AGPL-3.0 License.
|
# Released under the AGPL-3.0 License.
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from .utils import json_response
|
from .utils import json_response, get_request_real_ip
|
||||||
from apps.account.models import User
|
from apps.account.models import User
|
||||||
import traceback
|
import traceback
|
||||||
import time
|
import time
|
||||||
|
@ -31,7 +31,7 @@ class AuthenticationMiddleware(MiddlewareMixin):
|
||||||
return None
|
return None
|
||||||
access_token = request.headers.get('x-token') or request.GET.get('x-token')
|
access_token = request.headers.get('x-token') or request.GET.get('x-token')
|
||||||
if access_token and len(access_token) == 32:
|
if access_token and len(access_token) == 32:
|
||||||
x_real_ip = request.headers.get('x-real-ip', '')
|
x_real_ip = get_request_real_ip(request.headers)
|
||||||
user = User.objects.filter(access_token=access_token).first()
|
user = User.objects.filter(access_token=access_token).first()
|
||||||
if user and x_real_ip == user.last_ip and user.token_expired >= time.time() and user.is_active:
|
if user and x_real_ip == user.last_ip and user.token_expired >= time.time() and user.is_active:
|
||||||
request.user = user
|
request.user = user
|
||||||
|
|
|
@ -102,3 +102,13 @@ class DateTimeEncoder(json.JSONEncoder):
|
||||||
def generate_random_str(length: int = 4, is_digits: bool = True) -> str:
|
def generate_random_str(length: int = 4, is_digits: bool = True) -> str:
|
||||||
words = string.digits if is_digits else string.ascii_letters + string.digits
|
words = string.digits if is_digits else string.ascii_letters + string.digits
|
||||||
return ''.join(random.sample(words, length))
|
return ''.join(random.sample(words, length))
|
||||||
|
|
||||||
|
|
||||||
|
def get_request_real_ip(headers: dict):
|
||||||
|
x_real_ip = headers.get('x-real-ip')
|
||||||
|
if not x_real_ip:
|
||||||
|
x_forwarded_for = headers.get('x-forwarded-for')
|
||||||
|
if not x_forwarded_for:
|
||||||
|
return ''
|
||||||
|
x_real_ip = x_forwarded_for.split(',')[0]
|
||||||
|
return x_real_ip
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
* Released under the AGPL-3.0 License.
|
* Released under the AGPL-3.0 License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Form, Input, Icon, Button, Tabs, Modal} from 'antd';
|
import { Form, Input, Icon, Button, Tabs, Modal } from 'antd';
|
||||||
import styles from './login.module.css';
|
import styles from './login.module.css';
|
||||||
import history from 'libs/history';
|
import history from 'libs/history';
|
||||||
import {http, updatePermissions} from 'libs';
|
import { http, updatePermissions } from 'libs';
|
||||||
import logo from 'layout/logo-spug-txt.png';
|
import logo from 'layout/logo-spug-txt.png';
|
||||||
import envStore from 'pages/config/environment/store';
|
import envStore from 'pages/config/environment/store';
|
||||||
import appStore from 'pages/config/app/store';
|
import appStore from 'pages/config/app/store';
|
||||||
|
@ -46,7 +46,9 @@ class LoginIndex extends React.Component {
|
||||||
className: styles.tips,
|
className: styles.tips,
|
||||||
content: <div>
|
content: <div>
|
||||||
未能获取到客户端的真实IP,无法提供基于请求来源IP的合法性验证,详细信息请参考
|
未能获取到客户端的真实IP,无法提供基于请求来源IP的合法性验证,详细信息请参考
|
||||||
<a target="_blank" href="https://spug.dev" rel="noopener noreferrer">官方文档</a>。
|
<a target="_blank"
|
||||||
|
href="https://spug.dev/docs/practice/#%E5%AE%89%E5%85%A8%E6%80%A7%E5%AE%9E%E8%B7%B5%E6%8C%87%E5%8D%97"
|
||||||
|
rel="noopener noreferrer">官方文档</a>。
|
||||||
</div>,
|
</div>,
|
||||||
onOk: () => this.doLogin(data)
|
onOk: () => this.doLogin(data)
|
||||||
})
|
})
|
||||||
|
@ -122,11 +124,11 @@ class LoginIndex extends React.Component {
|
||||||
<a className={styles.links} title="官网" href="https://www.spug.dev" target="_blank"
|
<a className={styles.links} title="官网" href="https://www.spug.dev" target="_blank"
|
||||||
rel="noopener noreferrer">官网</a>
|
rel="noopener noreferrer">官网</a>
|
||||||
<a className={styles.links} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
<a className={styles.links} title="Github" href="https://github.com/openspug/spug" target="_blank"
|
||||||
rel="noopener noreferrer"><Icon type="github" /></a>
|
rel="noopener noreferrer"><Icon type="github"/></a>
|
||||||
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
<a title="文档" href="https://www.spug.dev/docs/about-spug/" target="_blank"
|
||||||
rel="noopener noreferrer">文档</a>
|
rel="noopener noreferrer">文档</a>
|
||||||
</div>
|
</div>
|
||||||
<div style={{color: 'rgba(0, 0, 0, .45)'}}>Copyright <Icon type="copyright" /> 2020 By OpenSpug</div>
|
<div style={{color: 'rgba(0, 0, 0, .45)'}}>Copyright <Icon type="copyright"/> 2020 By OpenSpug</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue