增加邮箱和手机号注册

pull/1/head
xiaoyu 5 years ago
parent cad199394b
commit d02a7a74b8
  1. 12
      fir_client/src/components/FirLogin.vue
  2. 251
      fir_client/src/components/FirRegist.vue
  3. 39
      fir_client/src/components/FirUserProfileInfo.vue
  4. 18
      fir_client/src/main.js
  5. 15
      fir_client/src/restful/index.js
  6. 2
      fir_client/src/router/download.js
  7. 2
      fir_client/src/router/short.js
  8. 10
      fir_client/src/utils/index.js
  9. 3
      fir_ser/api/urls.py
  10. 48
      fir_ser/api/utils/sendmsg/aliyunApi.py
  11. 51
      fir_ser/api/utils/sendmsg/emailApi.py
  12. 53
      fir_ser/api/utils/sendmsg/jiguangApi.py
  13. 83
      fir_ser/api/utils/sendmsg/sendmsg.py
  14. 10
      fir_ser/api/utils/storage/aliyunApi.py
  15. 28
      fir_ser/api/utils/tempcaches.py
  16. 42
      fir_ser/api/utils/utils.py
  17. 277
      fir_ser/api/views/login.py
  18. 18
      fir_ser/fir_ser/settings.py

@ -59,6 +59,7 @@
<script> <script>
import {loginFun, set_auth_token} from "../restful"; import {loginFun, set_auth_token} from "../restful";
import {checkEmail, checkphone} from "../utils";
export default { export default {
name: "FirLogin", name: "FirLogin",
@ -78,7 +79,16 @@
let password = this.form.password; let password = this.form.password;
let authcode = this.form.authcode; let authcode = this.form.authcode;
if (authcode.length === this.cptch.length) { if (authcode.length === this.cptch.length) {
if (this.isEmail(email) && password.length > 6) {
let checkp = checkphone(this.form.email);
let checke = checkEmail(this.form.email);
if (!checkp && !checke) {
this.$message({
message: '邮箱或者手机号输入有误',
type: 'error'
});
}
if (password.length > 6) {
loginFun(data => { loginFun(data => {
if (data.code == 1000) { if (data.code == 1000) {
this.$message({ this.$message({

@ -12,23 +12,21 @@
</div> </div>
</el-header> </el-header>
<el-main> <el-main v-if="allow_r">
<el-form ref="form" :model="form"> <el-form ref="form" :model="form">
<el-form-item> <el-form-item v-if="allow_ways.code">
<el-input v-model="form.email" prefix-icon="el-icon-user" placeholder="邮箱" autofocus></el-input> <el-input v-model="form.icode" prefix-icon="el-icon-postcard" placeholder="邀请码必填" clearable
></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-input v-model="form.password" prefix-icon="el-icon-lock" placeholder="密码" <el-input v-model="form.email" prefix-icon="el-icon-user" :placeholder="rutitle" autofocus
show-password></el-input> clearable></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.password2" prefix-icon="el-icon-lock" placeholder="确认密码"
show-password></el-input>
</el-form-item> </el-form-item>
<el-form-item style="height: 40px"> <el-form-item style="height: 40px">
<el-row style="height: 40px"> <el-row style="height: 40px">
<el-col :span="16"> <el-col :span="16">
@ -44,24 +42,30 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<!-- <el-form-item>-->
<!-- <el-input v-model="form.phone" prefix-icon="el-icon-mobile" placeholder="手机"--> <el-form-item>
<!-- maxlength="11"></el-input>--> <el-row>
<!-- </el-form-item>--> <el-col :span="16">
<el-input v-model="form.seicode" prefix-icon="el-icon-mobile"
<!-- <el-form-item>--> placeholder="验证码"/>
<!-- <el-row>--> </el-col>
<!-- <el-col :span="16">--> <el-col :span="8">
<!-- <el-input v-model="form.phonecode" prefix-icon="el-icon-mobile"--> <el-button type="info" @click="getphonecode" plain
<!-- placeholder="验证码"></el-input>--> style="margin:0px 4px;border-radius:4px;cursor:pointer;height: 40px">获取验证码
<!-- </el-col>--> </el-button>
<!-- <el-col :span="8">--> </el-col>
<!-- <el-button type="info" @click="getphonecode" plain--> </el-row>
<!-- style="margin:0px 4px;border-radius:4px;cursor:pointer;height: 40px">获取验证码--> </el-form-item>
<!-- </el-button>-->
<!-- </el-col>-->
<!-- </el-row>--> <el-form-item>
<!-- </el-form-item>--> <el-input v-model="form.password" prefix-icon="el-icon-lock" placeholder="密码"
show-password></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.password2" prefix-icon="el-icon-lock" placeholder="确认密码"
show-password></el-input>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="danger" @click="onRegist">注册</el-button> <el-button type="danger" @click="onRegist">注册</el-button>
@ -80,7 +84,8 @@
</template> </template>
<script> <script>
import {loginFun, registerFun} from "../restful"; import {getAuthTokenFun, registerFun} from "../restful";
import {checkEmail, checkphone} from "../utils";
export default { export default {
name: "FirRegist", name: "FirRegist",
@ -91,20 +96,49 @@
password: '', password: '',
password2: '', password2: '',
authcode: '', authcode: '',
srccode: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', srccode: '',
phonecode: '', seicode: '',
phone: '', authtoken: '',
icode: '',
auth_token: '',
}, },
cptch: {"cptch_image": '', "cptch_key": '', "length": 8}, cptch: {"cptch_image": '', "cptch_key": '', "length": 8},
allow_r: false,
allow_ways: {},
rutitle: '',
} }
}, },
methods: { methods: {
set_rtitle() {
this.rutitle = '';
this.rctitle = '';
if (this.allow_ways.sms) {
this.rutitle = this.rutitle + '手机号 ';
}
if (this.allow_ways.email) {
this.rutitle = this.rutitle + '邮箱 ';
}
this.rutitle = this.rutitle.trim().replace(' ', '或');
this.rctitle = this.rctitle.trim().replace(' ', '或');
},
get_auth_code() { get_auth_code() {
loginFun(data => { registerFun(data => {
if (data.code == 1000) { if (data.code == 1000) {
this.cptch = data.data; let jdata = data.data;
if (jdata.enable) {
this.allow_r = true;
this.allow_ways = jdata.ways;
this.set_rtitle();
this.cptch = data.data;
} else {
this.allow_r = false;
this.$message({
message: "该服务器不允许注册",
type: 'error'
});
}
} else { } else {
this.$message({ this.$message({
message: data.msg, message: data.msg,
@ -117,60 +151,137 @@
}); });
}, },
getphonecode() { getphonecode() {
}, let act = 'ways';
onRegist() { if (!this.docheck()) {
let email = this.form.email; return
let password = this.form.password; }
let password2 = this.form.password2; if (checkphone(this.form.email)) {
if (this.isEmail(email)) { act = 'sms'
let authcode = this.form.authcode; }
if (authcode.length === this.cptch.length) { if (checkEmail(this.form.email)) {
if (password === password2 && password.length >= 6) { act = 'email'
registerFun(data => { }
if (data.code == 1000) { let authcode = this.form.authcode;
this.$message({ if (authcode.length === this.cptch.length) {
message: '注册成功', let picode = {
type: 'success' "authcode": authcode,
}); "cptch_key": this.cptch.cptch_key,
this.$router.push({name: 'FirLogin'}) "icode": this.form.icode,
} else { };
this.$message({ getAuthTokenFun(data => {
message: data.msg, if (data.code === 1000) {
type: 'error' this.$notify({
}); title: '验证码',
this.get_auth_code(); message: '您正在进行注册,验证码已经发送您',
} type: 'success'
}, {
"methods": "POST",
"data": {
"username": email,
"password": password,
"password2": password2,
"authcode": authcode,
"cptch_key": this.cptch.cptch_key
}
}); });
this.form.auth_token = data.data.auth_token;
} else { } else {
this.$message({ this.$message({
message: '密码不一致或者密码长度小于6', message: data.msg,
type: 'warning' type: 'error'
}); });
} }
}, {"methods": 'GET', 'data': {'act': act, 'target': this.form.email, 'ext': picode}})
} else {
this.$message({
message: '图片验证码有误',
type: 'warning'
});
}
},
docheck() {
let checkp = checkphone(this.form.email);
let checke = checkEmail(this.form.email);
if (this.allow_ways.sms && this.allow_ways.email) {
if (!checke && !checkp) {
this.$message({
message: '请输入正确的邮箱地址或手机号码',
type: 'warning'
});
return 0
}
} else {
if (this.allow_ways.email) {
if (!checke) {
this.$message({
message: '请输入正确的邮箱地址',
type: 'warning'
});
return 0
}
}
if (this.allow_ways.sms) {
if (!checkp) {
this.$message({
message: '请输入正确的手机号码',
type: 'warning'
});
return 0
}
}
}
if (this.allow_ways.code && this.form.icode.length === 0) {
this.$message({
message: '请输入邀请码',
type: 'warning'
});
return 0
}
return 1
},
onRegist() {
let email = this.form.email;
let password = this.form.password;
let password2 = this.form.password2;
if (!this.docheck()) {
return
}
let authcode = this.form.authcode;
if (authcode.length === this.cptch.length) {
if (password === password2 && password.length >= 6) {
registerFun(data => {
if (data.code == 1000) {
this.$message({
message: '注册成功',
type: 'success'
});
this.$router.push({name: 'FirLogin'})
} else {
this.$message({
message: data.msg,
type: 'error'
});
this.get_auth_code();
}
}, {
"methods": "POST",
"data": {
"username": email,
"password": password,
"password2": password2,
"auth_token": this.form.auth_token,
"auth_key": this.form.seicode
}
});
} else { } else {
this.$message({ this.$message({
message: '验证码有误', message: '密码不一致或者密码长度小于6',
type: 'warning' type: 'warning'
}); });
} }
} else { } else {
this.$message({ this.$message({
message: '请输入正确的邮箱地址', message: '验证码有误',
type: 'warning' type: 'warning'
}); });
} }
}, },
onLogin() { onLogin() {
this.$router.push({name: 'FirLogin'}) this.$router.push({name: 'FirLogin'})

@ -18,12 +18,13 @@
placeholder="下载页域名"></el-input> placeholder="下载页域名"></el-input>
</el-col> </el-col>
<el-col :span="2"> <el-col :span="2">
<el-button icon="el-icon-edit" @click="changeQQValue"> <el-button icon="el-icon-edit" @click="changeDomainValue">
</el-button> </el-button>
</el-col> </el-col>
<el-col :span="4" v-if="editdomain_name === true"> <el-col :span="4" v-if="editdomain_name === true">
<el-button type="success" @click="saveQQ" plain <el-button type="success" @click="saveDomain" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px">保存 style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px;background-color: #f56c6c;color: wheat">
保存
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
@ -41,7 +42,9 @@
</el-col> </el-col>
<el-col :span="4" v-if="editposition === true"> <el-col :span="4" v-if="editposition === true">
<el-button type="success" @click="savePositionValue" plain <el-button type="success" @click="savePositionValue" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px">保存 style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px;background-color: #f56c6c;color: wheat">
保存
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
@ -60,7 +63,8 @@
</el-col> </el-col>
<el-col :span="4" v-if="editphone === true"> <el-col :span="4" v-if="editphone === true">
<el-button type="success" @click="savePhone" plain <el-button type="success" @click="savePhone" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px">保存 style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px;background-color: #f56c6c;color: wheat">
保存
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
@ -74,7 +78,8 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-button type="info" @click="getphonecode" plain <el-button type="info" @click="getphonecode" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px">获取验证码 style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px;background-color: #ecf5ff;color: #dd6161">
获取验证码
</el-button> </el-button>
</el-col> </el-col>
@ -88,7 +93,7 @@
</template> </template>
<script> <script>
import {userinfos} from '../restful' import {userinfos, getAuthTokenFun} from '../restful'
import {deepCopy} from "../utils"; import {deepCopy} from "../utils";
export default { export default {
@ -104,9 +109,9 @@
editposition: false editposition: false
} }
}, methods: { }, methods: {
saveQQ() { saveDomain() {
this.updateUserInfo({"methods": 'PUT', 'data': this.userinfo}); this.updateUserInfo({"methods": 'PUT', 'data': this.userinfo});
this.changeQQValue() this.changeDomainValue()
}, },
savePositionValue() { savePositionValue() {
this.updateUserInfo({"methods": 'PUT', 'data': this.userinfo}); this.updateUserInfo({"methods": 'PUT', 'data': this.userinfo});
@ -120,6 +125,7 @@
userinfos(data => { userinfos(data => {
if (data.code === 1000) { if (data.code === 1000) {
let phonenumber = null; let phonenumber = null;
if (data.data.sms_code) { if (data.data.sms_code) {
phonenumber = this.userinfo.mobile; phonenumber = this.userinfo.mobile;
this.$notify({ this.$notify({
@ -164,7 +170,7 @@
} }
}, },
changeQQValue() { changeDomainValue() {
this.editdomain_name = !this.editdomain_name; this.editdomain_name = !this.editdomain_name;
if (this.$refs.domain_name.$el.children[0].style.backgroundColor) { if (this.$refs.domain_name.$el.children[0].style.backgroundColor) {
this.$refs.domain_name.$el.children[0].style.backgroundColor = '' this.$refs.domain_name.$el.children[0].style.backgroundColor = ''
@ -173,7 +179,18 @@
} }
}, },
getphonecode() { getphonecode() {
this.updateUserInfo({"methods": 'GET', 'data': {'act': 'sms'}}); getAuthTokenFun(data => {
if (data.code === 1000) {
this.$notify({
title: '验证码',
message: '您正在修改手机号码,验证码已经发送您手机',
type: 'success'
});
}
this.userinfo.auth_token = data.data.auth_token;
}, {"methods": 'GET', 'data': {'act': 'sms', 'phone': this.userinfo.mobile}})
// this.updateUserInfo({"methods": 'GET', 'data': {'act': 'sms','phone':this.userinfo.mobile}});
} }
}, mounted() { }, mounted() {

@ -83,7 +83,17 @@ import {
Slider, Slider,
DropdownMenu, DropdownMenu,
Dropdown, Dropdown,
Breadcrumb, Avatar, DropdownItem, RadioButton, RadioGroup, OptionGroup, Progress, Timeline, TimelineItem, Card Breadcrumb,
Avatar,
DropdownItem,
RadioButton,
RadioGroup,
OptionGroup,
Progress,
Timeline,
TimelineItem,
Card,
Notification
} from "element-ui"; } from "element-ui";
Vue.use(Progress); Vue.use(Progress);
@ -132,10 +142,10 @@ Vue.use(Tag);
Vue.use(Tooltip); Vue.use(Tooltip);
Vue.use(Switch); Vue.use(Switch);
Vue.prototype.$message = Message; Vue.prototype.$message = Message;
Vue.prototype.$notify = Notification;
// Vue.use(MessageBox); Vue.prototype.$loading = Loading.service;
Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
// Vue.use(ElementUI); // Vue.use(ElementUI);
Vue.use(Vuex); Vue.use(Vuex);

@ -175,6 +175,21 @@ export function loginFun(callBack, params, load = true) {
); );
} }
/**获取验证token */
export function getAuthTokenFun(callBack, params, load = true) {
getData(
params.methods,
USERSEVER + '/auth',
params.data,
data => {
callBack(data);
},
load,
true,
true
);
}
/**用户注册 */ /**用户注册 */
export function registerFun(callBack, params, load = true) { export function registerFun(callBack, params, load = true) {
getData( getData(

@ -18,7 +18,7 @@ const router = new VueRouter({
path: '/:short', path: '/:short',
name: 'FirDownload', name: 'FirDownload',
// component: () => import("@/components/ShortDownload") // component: () => import("@/components/ShortDownload")
component: ()=>import("@/components/FirDownload") component: () => import("@/components/FirDownload")
} }
] ]
}); });

@ -17,7 +17,7 @@ const router = new VueRouter({
{ {
path: '/:short', path: '/:short',
name: 'FirDownload', name: 'FirDownload',
component: ()=>import("@/components/ShortDownload") component: () => import("@/components/ShortDownload")
// component: () => import("@/components/FirDownload") // component: () => import("@/components/FirDownload")
} }
] ]

@ -260,4 +260,14 @@ export function deepCopy(data) {
} }
} }
return obj; return obj;
}
export function checkEmail(email) {
let re = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
return re.test(email);
}
export function checkphone(email) {
let re = /^1\d{10}$/;
return re.test(email);
} }

@ -16,7 +16,7 @@ Including another URLconf
from django.contrib import admin from django.contrib import admin
from django.urls import path, re_path, include from django.urls import path, re_path, include
from api.views.login import LoginView, UserInfoView, RegistView from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView
from api.views.logout import LogoutView from api.views.logout import LogoutView
from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView
from api.views.download import ShortDownloadView from api.views.download import ShortDownloadView
@ -32,6 +32,7 @@ from api.views.supersign import DeveloperView, SuperSignUsedView, AppUDIDUsedVie
urlpatterns = [ urlpatterns = [
# path("",include(router.urls)), # path("",include(router.urls)),
re_path("^login", LoginView.as_view()), re_path("^login", LoginView.as_view()),
re_path("^auth", AuthorizationView.as_view()),
re_path("^register", RegistView.as_view()), re_path("^register", RegistView.as_view()),
re_path("^logout", LogoutView.as_view()), re_path("^logout", LogoutView.as_view()),
re_path("^apps$", AppsView.as_view()), re_path("^apps$", AppsView.as_view()),

@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: liuyu
# date: 2020/3/22
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import json
class AliMsgSender(object):
def __init__(self, access_key, secret_key, sing_name, template_code, region_id='cn-hangzhou'):
self.regionid = region_id
self.sing_name = sing_name
self.template_code = template_code
self.client = AcsClient(access_key, secret_key, region_id)
def send_msg(self, template_code, phone, code):
request = CommonRequest()
request.set_accept_format('json')
request.set_domain('dysmsapi.aliyuncs.com')
request.set_method('POST')
request.set_protocol_type('https')
request.set_version('2017-05-25')
request.set_action_name('SendSms')
request.add_query_param('RegionId', self.regionid)
request.add_query_param('PhoneNumbers', phone)
request.add_query_param('SignName', self.sing_name)
request.add_query_param('TemplateCode', template_code)
request.add_query_param('TemplateParam', {'code': code})
response = self.client.do_action_with_exception(request)
data = json.loads(response)
if data.get('Code') == 'OK':
return True, data.get('Message')
else:
return False, data.get('Message')
def send_register_msg(self, phone, code):
return self.send_msg(self.template_code.get('register'), phone, code)
def send_change_msg(self, phone, code):
return self.send_msg(self.template_code.get('change'), phone, code)
def send_login_msg(self, phone, code):
return self.send_msg(self.template_code.get('login'), phone, code)

@ -0,0 +1,51 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: liuyu
# date: 2020/3/22
from django.conf import settings
from django.core.mail import send_mail
class EmailMsgSender(object):
def __init__(self, email_host, email_port, subject, username, password, form, template_code):
self.email_host = email_host
self.email_port = email_port
self.username = username
self.password = password
self.form = form
self.subject = subject
self.template_code = template_code
self.set_settings()
def set_settings(self):
settings.EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
settings.EMAIL_HOST = self.email_host
settings.EMAIL_PORT = self.email_port
settings.EMAIL_HOST_USER = self.username
settings.EMAIL_HOST_PASSWORD = self.password
settings.EMAIL_FROM = self.form
def send_msg(self, template_code, email, code):
try:
response = send_mail(self.subject % {'code': ''}, template_code % {'code': code}, self.form, [email], )
if response == 1:
return True, 'OK'
else:
return False, 'Send Email Failed'
except Exception as e:
return False, e
def send_register_msg(self, phone, code):
return self.send_msg(self.template_code.get('register'), phone, code)
def send_change_msg(self, phone, code):
return self.send_msg(self.template_code.get('change'), phone, code)
def send_login_msg(self, phone, code):
return self.send_msg(self.template_code.get('login'), phone, code)
def send_email_msg(self, email, text):
response = send_mail(self.subject, text, self.form, email, )
return response

@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: liuyu
# date: 2020/3/22
import requests
import json
class JiGuangMsgSender(object):
BASE_URL = 'https://api.sms.jpush.cn/v1/'
def __init__(self, app_key, master_secret, sign_id, template_code):
self.template_code = template_code
self.sign_id = sign_id
self.session = requests.Session()
self.session.auth = (app_key, master_secret)
def _post(self, end_point, body):
return self._request('POST', end_point, body)
def _request(self, method, end_point, body=None):
uri = self.BASE_URL + end_point
if body is not None:
body = json.dumps(body)
r = self.session.request(method, uri, data=body)
if 0 == len(r.content):
return r.status_code
else:
return r.json()
def send_msg(self, template_code, phone, code):
body = {
'mobile': phone,
'temp_id': template_code,
'temp_para': {'code': code},
'sign_id': self.sign_id
}
response = self._post('messages', body)
if response.get('msg_id', None):
return True, response.get('msg_id')
else:
return False, response.get('error')
def send_register_msg(self, phone, code):
return self.send_msg(self.template_code.get('register'), phone, code)
def send_change_msg(self, phone, code):
return self.send_msg(self.template_code.get('change'), phone, code)
def send_login_msg(self, phone, code):
return self.send_msg(self.template_code.get('login'), phone, code)

@ -0,0 +1,83 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: liuyu
# date: 2020/3/23
from api.models import UserInfo
from .aliyunApi import AliMsgSender
from .emailApi import EmailMsgSender
from .jiguangApi import JiGuangMsgSender
import json, time, base64
from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE
from django.core.cache import cache
import logging
logger = logging.getLogger(__file__)
class SendMessage(object):
def __init__(self, type):
'''
:param type: sms or email
'''
self.type = type
try:
if type == 'sms':
self.sender = self._get_sms_sender()
elif type == 'email':
self.sender = self._get_email_sender()
if self.sender is None:
raise
except Exception as e:
logger.error("get %s sender failed Exception:%s" % (type, e))
self.sender = None
def send_register_msg(self, target, code):
status, msg = self.sender.send_register_msg(target, code)
logger.info("send_register_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg))
return status, msg
def send_change_msg(self, target, code):
status, msg = self.sender.send_change_msg(target, code)
logger.info("send_change_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg))
return status, msg
def send_login_msg(self, target, code):
status, msg = self.sender.send_login_msg(target, code)
logger.info("send_login_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg))
return status, msg
def send_email_msg(self, email, text):
if self.type == 'email':
status, msg = self.sender.send_email_msg(email, text)
logger.info("send_email_msg target:%s text:%s status:%s msg:%s" % (email, text, status, msg))
return status, msg
def _get_email_sender(self):
return self._get_default_sender(0)
def _get_sms_sender(self):
return self._get_default_sender(1)
def _get_default_sender(self, type):
'''
sender_type :
0: 邮件
1: 阿里云
2: 极光
'''
sender_lists = THIRD_PART_CONFIG.get('sender')
for sender in sender_lists:
if sender.get("active", None):
sender_type = sender.get('type', None)
auth = sender.get('auth', {})
if sender_type == 0 and type == 0:
return EmailMsgSender(**auth)
if sender_type == 1:
return AliMsgSender(**auth)
elif sender_type == 2:
return JiGuangMsgSender(**auth)
else:
continue
return None

@ -54,11 +54,11 @@ class StsToken(object):
class AliYunOss(object): class AliYunOss(object):
def __init__(self, access_key, secret_key, bucket_name, endpoint, sts_role_arn, is_https, domain_name=None): def __init__(self, access_key, secret_key, bucket_name, endpoint, sts_role_arn, is_https, domain_name=None):
self.access_key_id = access_key or os.getenv('OSS_TEST_STS_ID', 'LTAI4FeTyvz74CHKCbYuTDGc') self.access_key_id = access_key
self.access_key_secret = secret_key or os.getenv('OSS_TEST_STS_KEY', 'uineAEE7tp1d1w4Mv0yLqxvV0IVNTy') self.access_key_secret = secret_key
self.bucket_name = bucket_name or os.getenv('OSS_TEST_BUCKET', 'fir-storage') self.bucket_name = bucket_name
self.endpoint = endpoint or os.getenv('OSS_TEST_ENDPOINT', 'oss-cn-beijing.aliyuncs.com') self.endpoint = endpoint
self.sts_role_arn = sts_role_arn or os.getenv('OSS_TEST_STS_ARN', 'acs:ram::1622120977387033:role/appstorage') self.sts_role_arn = sts_role_arn
self.region_id = '-'.join(self.endpoint.split('.')[0].split("-")[1:3]) self.region_id = '-'.join(self.endpoint.split('.')[0].split("-")[1:3])
self.token = StsToken() self.token = StsToken()
self.is_https = is_https self.is_https = is_https

@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 9月
# author: NinEveN
# date: 2020/9/24
from django.core.cache import cache
import base64
class tmpCache(object):
@staticmethod
def set_tmp_cache(key, token, target, limit=60 * 5):
nkey = '%s:%s' % (key, token)
nkey = base64.b64encode(nkey.encode("utf-8")).decode("utf-8")
cache.set(nkey, target, limit)
@staticmethod
def get_tmp_cache(key, token):
nkey = '%s:%s' % (key, token)
nkey = base64.b64encode(nkey.encode("utf-8")).decode("utf-8")
return cache.get(nkey)
@staticmethod
def del_tmp_cache(key, token):
nkey = base64.b64encode('%s:%s'.encode("utf-8") % (key, token))
return cache.delete(nkey)

@ -10,9 +10,14 @@ from api.models import APPSuperSignUsedInfo, APPToDeveloper, \
from api.utils.app.randomstrings import make_app_uuid from api.utils.app.randomstrings import make_app_uuid
from api.utils.storage.localApi import LocalStorage from api.utils.storage.localApi import LocalStorage
from api.utils.storage.storage import Storage from api.utils.storage.storage import Storage
from api.utils.tempcaches import tmpCache
from api.utils.TokenManager import DownloadToken, generateNumericTokenOfLength
from api.utils.sendmsg.sendmsg import SendMessage
from django.db.models import Sum from django.db.models import Sum
from captcha.models import CaptchaStore from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url from captcha.helpers import captcha_image_url
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -122,3 +127,40 @@ def is_valid_domain(value):
r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$' r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$'
) )
return True if pattern.match(value) else False return True if pattern.match(value) else False
def is_valid_phone(value):
phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$')
return True if value and re.search(phone_pat, value) else False
def is_valid_email(email):
try:
validate_email(email)
return True
except ValidationError:
return False
def get_sender_token(sender, user_id, target):
sms_token_obj = DownloadToken()
code = generateNumericTokenOfLength(6)
token = sms_token_obj.make_token(code, time_limit=300, key=user_id)
tmpCache.set_tmp_cache(user_id, token, target)
sender.send_change_msg(target, code)
return token, code
def get_sender_sms_token(key, phone):
sender = SendMessage('sms')
return get_sender_token(sender, key, phone)
def is_valid_sender_code(key, token, code):
sms_token_obj = DownloadToken()
return sms_token_obj.verify_token(token, code), tmpCache.get_tmp_cache(key, token)
def get_sender_email_token(key, email):
sender = SendMessage('email')
return get_sender_token(sender, key, email)

@ -5,13 +5,13 @@ from api.utils.serializer import UserInfoSerializer
from django.core.cache import cache from django.core.cache import cache
from rest_framework.views import APIView from rest_framework.views import APIView
import binascii import binascii
import os, datetime, re import os, datetime, json
from api.utils.utils import get_captcha, valid_captcha, is_valid_domain from api.utils.utils import get_captcha, valid_captcha, is_valid_domain, is_valid_phone, \
from api.utils.TokenManager import DownloadToken, generateNumericTokenOfLength get_sender_sms_token, is_valid_email, is_valid_sender_code, get_sender_email_token
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 fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN from fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN, REGISTER
from api.utils.storage.caches import login_auth_failed, set_default_app_wx_easy from api.utils.storage.caches import login_auth_failed, set_default_app_wx_easy
import logging import logging
@ -30,53 +30,51 @@ class LoginView(APIView):
def post(self, request): def post(self, request):
response = BaseResponse() response = BaseResponse()
receive = request.data receive = request.data
username = receive.get("username", None)
if request.method == 'POST': is_valid = valid_captcha(receive.get("cptch_key", None), receive.get("authcode", None), username)
username = receive.get("username", None) if is_valid:
is_valid = valid_captcha(receive.get("cptch_key", None), receive.get("authcode", None), username) if login_auth_failed("get", username):
if is_valid: password = receive.get("password")
if login_auth_failed("get", username): user = auth.authenticate(username=username, password=password)
password = receive.get("password") logger.info("username:%s password:%s" % (username, password))
user = auth.authenticate(username=username, password=password) if user is not None:
logger.info("username:%s password:%s" % (username, password)) if user.is_active:
if user is not None: login_auth_failed("del", username)
if user.is_active: # update the token
login_auth_failed("del", username) key = self.generate_key()
# update the token now = datetime.datetime.now()
key = self.generate_key() user_info = UserInfo.objects.get(pk=user.pk)
now = datetime.datetime.now()
user_info = UserInfo.objects.get(pk=user.pk) auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), key])
cache.set(auth_key, {'uid': user_info.uid, 'username': user_info.username}, 3600 * 24 * 7)
auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), key]) Token.objects.create(user=user, **{"access_token": key, "created": now})
cache.set(auth_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, )
data = serializer.data
serializer = UserInfoSerializer(user_info, ) response.msg = "验证成功!"
data = serializer.data response.userinfo = data
response.msg = "验证成功!" response.token = key
response.userinfo = data
response.token = key
else:
response.msg = "用户被禁用"
response.code = 1005
else: else:
login_auth_failed("set", username) response.msg = "用户被禁用"
try: response.code = 1005
UserInfo.objects.get(username=username)
response.msg = "密码或者账户有误"
response.code = 1002
except UserInfo.DoesNotExist:
response.msg = "用户不存在!"
response.code = 1003
else: else:
response.code = 1006 login_auth_failed("set", username)
logger.error("username:%s failed too try , locked" % (username,)) try:
response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试" UserInfo.objects.get(username=username)
response.msg = "密码或者账户有误"
response.code = 1002
except UserInfo.DoesNotExist:
response.msg = "用户不存在!"
response.code = 1003
else: else:
response.code = 1001 response.code = 1006
response.msg = "验证码有误" logger.error("username:%s failed too try , locked" % (username,))
response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试"
else:
response.code = 1001
response.msg = "验证码有误"
return Response(response.dict) return Response(response.dict)
def get(self, request): def get(self, request):
response = BaseResponse() response = BaseResponse()
@ -93,21 +91,28 @@ class RegistView(APIView):
receive = request.data receive = request.data
username = receive.get("username", None) username = receive.get("username", None)
is_valid = valid_captcha(receive.get("cptch_key", None), receive.get("authcode", None), username) act = 'sms'
if is_valid: if is_valid_email(username):
act = 'email'
is_valid, target = is_valid_sender_code(act, receive.get("auth_token", None), receive.get("auth_key", None))
if is_valid and str(target) == str(username):
if login_auth_failed("get", username): if login_auth_failed("get", username):
password = receive.get("password") password = receive.get("password")
password2 = receive.get("password2") password2 = receive.get("password2")
if password == password2: if password == password2:
try: try:
UserInfo.objects.get(username=username) UserInfo.objects.get(username=username)
login_auth_failed("set", username) login_auth_failed("set", username)
response.msg = "邮箱已经存在,请更换其他邮箱" response.msg = "邮箱已经存在,请更换其他邮箱"
response.code = 1002 response.code = 1002
except UserInfo.DoesNotExist: except UserInfo.DoesNotExist:
user_obj = UserInfo.objects.create_user(username, email=username, password=password, if is_valid_email(username):
first_name=username[:8])
user_obj = UserInfo.objects.create_user(username, email=username, password=password,
first_name=username[:8])
else:
user_obj = UserInfo.objects.create_user(username, mobile=username, password=password,
first_name=username[:8])
if user_obj: if user_obj:
response.msg = "注册成功" response.msg = "注册成功"
response.code = 1000 response.code = 1000
@ -120,13 +125,18 @@ class RegistView(APIView):
response.msg = "用户注册失败次数过多,已被锁定,请1小时之后再次尝试" response.msg = "用户注册失败次数过多,已被锁定,请1小时之后再次尝试"
else: else:
response.code = 1001 response.code = 1001
response.msg = "验证码有误" response.msg = "邮件或短信验证码有误"
return Response(response.dict) return Response(response.dict)
def get(self, request): def get(self, request):
response = BaseResponse() response = BaseResponse()
response.data = get_captcha() response.data = {}
allow_f = REGISTER.get("enable")
if allow_f:
response.data = get_captcha()
response.data['ways'] = REGISTER.get("ways")
response.data['enable'] = allow_f
return Response(response.dict) return Response(response.dict)
@ -137,13 +147,6 @@ class UserInfoView(APIView):
res = BaseResponse() res = BaseResponse()
serializer = UserInfoSerializer(request.user) serializer = UserInfoSerializer(request.user)
res.data = serializer.data res.data = serializer.data
act = request.query_params.get("act", None)
if act and act == "sms":
sms_token_obj = DownloadToken()
sms_code = generateNumericTokenOfLength(6)
sms_token = sms_token_obj.make_token(sms_code)
res.data["sms_token"] = sms_token
res.data["sms_code"] = sms_code
return Response(res.dict) return Response(res.dict)
@ -211,18 +214,21 @@ class UserInfoView(APIView):
request.user.job = data.get("job", request.user.job) request.user.job = data.get("job", request.user.job)
request.user.first_name = data.get("first_name", request.user.first_name) request.user.first_name = data.get("first_name", request.user.first_name)
sms_token = data.get("sms_token", None) sms_token = data.get("auth_token", None)
if sms_token: if sms_token:
sms_token_obj = DownloadToken() status, target = is_valid_sender_code(request.user.uid, sms_token, data.get("sms_code", None))
if sms_token_obj.verify_token(sms_token, data.get("sms_code", None)): mobile = data.get("mobile", request.user.mobile)
mobile = data.get("mobile", request.user.mobile) if target == mobile:
phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$') if is_valid_phone(mobile):
if mobile and re.search(phone_pat, mobile):
request.user.mobile = data.get("mobile", request.user.mobile) request.user.mobile = data.get("mobile", request.user.mobile)
else: else:
res.code = 1005 res.code = 1005
res.msg = "手机号校验失败" res.msg = "手机号异常"
return Response(res.dict) return Response(res.dict)
else:
res.code = 1005
res.msg = "手机号校验失败"
return Response(res.dict)
try: try:
request.user.save() request.user.save()
@ -238,3 +244,132 @@ class UserInfoView(APIView):
return Response(res.dict) return Response(res.dict)
return Response(res.dict) return Response(res.dict)
class AuthorizationView(APIView):
def get(self, request):
res = BaseResponse()
res.data = {}
act = request.query_params.get("act", None)
target = request.query_params.get("target", None)
ext = request.query_params.get("ext", None)
if ext:
ext = json.loads(ext)
ways = REGISTER.get("ways")
if ways.get('code') and ext and ext.get('icode'):
if ext.get('icode') == '689888666':
pass
else:
res.code = 1008
res.msg = "邀请码已失效"
return Response(res.dict)
if ext and valid_captcha(ext.get("cptch_key", None), ext.get("authcode", None), target):
pass
else:
res.code = 1008
res.msg = "图片验证码有误"
return Response(res.dict)
times_key = "register_%s_%s" % (act, target)
if act == "sms":
if is_valid_phone(target):
if login_auth_failed("get", times_key):
login_auth_failed("set", times_key)
if UserInfo.objects.filter(mobile=target):
res.code = 1005
res.msg = "手机号已经存在"
else:
token, code = get_sender_sms_token(act, target)
res.data["auth_token"] = token
else:
res.code = 1009
res.msg = "该手机号今日注册次数已经达到上限"
else:
res.code = 1005
res.msg = "手机号校验失败"
elif act == "email":
if is_valid_email(target):
if login_auth_failed("get", times_key):
login_auth_failed("set", times_key)
if UserInfo.objects.filter(email=target):
res.code = 1005
res.msg = "邮箱已经存在"
else:
token, code = get_sender_email_token(act, target)
res.data["auth_token"] = token
else:
res.code = 1009
res.msg = "该邮箱今日注册次数已经达到上限"
else:
res.code = 1006
res.msg = "邮箱校验失败"
elif act == "ways":
if ways['sms']:
pass
elif ways['email']:
pass
elif ways['code']:
pass
else:
pass
else:
res.code = 1007
res.msg = "信息发送失败"
return Response(res.dict)
class AuthorizationViewbak(APIView):
# authentication_classes = [ExpiringTokenAuthentication, ]
def get(self, request):
res = BaseResponse()
res.data = {}
act = request.query_params.get("act", None)
target = request.query_params.get("target", None)
ext = request.query_params.get("ext", None)
ways = REGISTER.get("ways")
if ways.get('code') and ext:
if ext == '689888666':
pass
else:
res.code = 1008
res.msg = "邀请码已失效"
return Response(res.dict)
if act == "sms":
if is_valid_phone(target) and str(request.user.mobile) != str(target):
token, code = get_sender_sms_token(request.user.uid, target)
res.data["auth_token"] = token
else:
res.code = 1005
res.msg = "手机号校验失败"
elif act == "email":
if is_valid_email(target) and str(request.user.email) != str(target):
token, code = get_sender_email_token(request.user.uid, target)
res.data["auth_token"] = token
else:
res.code = 1006
res.msg = "邮箱校验失败"
elif act == "ways":
if ways['sms']:
pass
elif ways['email']:
pass
elif ways['code']:
pass
else:
pass
else:
res.code = 1007
res.msg = "信息发送失败"
return Response(res.dict)

@ -168,6 +168,24 @@ REST_FRAMEWORK_EXTENSIONS = {
'DEFAULT_USE_CACHE': 'default', 'DEFAULT_USE_CACHE': 'default',
} }
# 注册方式,如果启用sms或者email 需要配置 THIRD_PART_CONFIG.sender 信息
REGISTER = {
"enable": True,
"ways": {
'sms': True, # 短信注册
'email': True, # 邮件注册
'code': False, # 邀请码注册,邀请码必填写,需要和短信,邮件一起使用
}
}
LOGIN = {
"ways": [
{'sms': False}, # 短信登录
{'email': True}, # 邮件登录
{'code': False}, # 密码登录
]
}
THIRD_PART_CONFIG = { THIRD_PART_CONFIG = {
# APP存储配置 # APP存储配置
'storage': [ 'storage': [

Loading…
Cancel
Save