Skip to content

Commit b3476e0

Browse files
author
zhangjie
committed
change something
1 parent 9e2b6f8 commit b3476e0

File tree

17 files changed

+228
-63
lines changed

17 files changed

+228
-63
lines changed

api/app.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ def create_app():
1818
db.init_app(app)
1919

2020
from .auth import api_auth as auth_blueprint
21-
app.register_blueprint(auth_blueprint, url_prefix='/auth')
21+
app.register_blueprint(auth_blueprint, url_prefix='/api')
22+
23+
from .users import api_user as user_blueprint
24+
app.register_blueprint(user_blueprint, url_prefix='/api')
2225

2326
return app

api/auth/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from flask import Blueprint
22
from ..app import api
3-
4-
from .resources.foo import Foo
3+
from .resources.login import LoginApi
4+
from .resources.logout import LogOutApi
55

66
api_auth = Blueprint('auth', __name__)
77

8-
api.add_resource(Foo, '/todos/<int:id>')
8+
api.add_resource(LoginApi, '/login')
9+
api.add_resource(LogOutApi, '/logout')
10+
911
api.init_app(api_auth)
1012

1113
"""Initialize this class with the given :class:`flask.Flask`

api/auth/resources/foo.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

api/auth/resources/login.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from flask_restful import Resource, reqparse
2+
from flask import jsonify
3+
4+
from api.models.user import User
5+
6+
7+
class LoginApi(Resource):
8+
def __init__(self):
9+
self.reqparse = reqparse.RequestParser()
10+
self.reqparse.add_argument('username', type=str, required=True, help='用户名不能为空', location='json')
11+
self.reqparse.add_argument('password', type=str, required=True, help='密码不能为空', location='json')
12+
super(LoginApi, self).__init__()
13+
14+
def get(self):
15+
return {'task': 'Say "Hello, World!"'}
16+
17+
def post(self):
18+
args = self.reqparse.parse_args()
19+
username = args.get('username')
20+
password = args.get('password')
21+
22+
user = User.query.filter_by(username=username).first()
23+
if user and user.verify_password(password):
24+
token = user.generate_auth_token().decode('ascii')
25+
user.token = token
26+
27+
return jsonify({'data': user.to_dict()})
28+
29+
return {'errcode': 422, 'errmsg': '用户名或者密码不对'}, 422

api/auth/resources/logout.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from flask_restful import Resource, reqparse
2+
from flask import jsonify
3+
4+
from api.models.user import User
5+
from api.auth_token import token_auth
6+
7+
8+
class LogOutApi(Resource):
9+
decorators = [token_auth.login_required]
10+
11+
def __init__(self):
12+
self.reqparse = reqparse.RequestParser()
13+
self.reqparse.add_argument('token', type=str, required=True, help='token不能为空', location='json')
14+
super(LogOutApi, self).__init__()
15+
16+
def post(self):
17+
args = self.reqparse.parse_args()
18+
token = args.get('token')
19+
20+
user = User.query.filter_by(token=token).first()
21+
if not user:
22+
return {'errcode': 422, 'errmsg': 'Token失效或者不对'}, 422
23+
24+
user.token = None
25+
return jsonify({})

api/auth_token.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
2+
3+
from . import app
4+
from .models.user import User
5+
from .errors import unauthorized, forbidden
6+
7+
token_auth = HTTPTokenAuth(scheme='Bearer')
8+
9+
10+
@token_auth.verify_token
11+
def verify_token(token):
12+
print(token)
13+
if token:
14+
user = User.verify_auth_token(token)
15+
return user is not None
16+
return False
17+
18+
19+
@token_auth.error_handler
20+
def auth_error():
21+
return unauthorized('token过期或者不存在')

api/base_model.py

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,21 @@ def enum_to_value(data):
1313
new_data = data
1414
return new_data
1515

16-
@staticmethod
17-
def enum_to_name(data):
18-
if not data:
19-
return None
20-
try:
21-
new_data = data.name
22-
except Exception:
23-
new_data = data
24-
return new_data
25-
26-
'''
16+
"""
2717
:param
2818
enum_type: show enum name or value
2919
extra_kw : extra property value
30-
extra_dict: extra dict
20+
extra_dict: extra dict
3121
remove_key: del dict key
32-
@:return
22+
@:return
3323
return new dict
34-
'''
24+
"""
3525

36-
def to_dict(self, enum_type='name', extra_kw=None, extra_dict=None, remove_key=list()):
37-
model_field = [v for v in self.__dict__.keys() if not v.startswith('_') and v not in remove_key]
26+
def to_dict(self, extra_dict=None, remove_key=None):
27+
model_field = [v for v in self.__dict__.keys() if not v.startswith('_') and v not in (remove_key or [])]
3828
result = dict()
3929
for info in model_field:
40-
if enum_type == 'name':
41-
result[info] = self.enum_to_name(getattr(self, info))
42-
else:
43-
result[info] = self.enum_to_value(getattr(self, info))
44-
45-
if extra_kw and isinstance(extra_kw, list):
46-
for info in extra_kw:
47-
if enum_type == 'name':
48-
result[info] = self.enum_to_name(getattr(self, info))
49-
else:
50-
result[info] = self.enum_to_value(getattr(self, info))
30+
result[info] = self.enum_to_value(getattr(self, info))
5131

5232
if extra_dict and isinstance(extra_dict, dict):
5333
for k, v in extra_dict.items():

api/errors.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from flask import jsonify
2+
3+
4+
class ValidationError(ValueError):
5+
pass
6+
7+
8+
def bad_request(message):
9+
response = jsonify({'error': 'bad request', 'message': message})
10+
response.status_code = 400
11+
return response
12+
13+
14+
def unauthorized(message):
15+
response = jsonify({'error': 'unauthorized', 'message': message})
16+
response.status_code = 401
17+
return response
18+
19+
20+
def forbidden(message):
21+
response = jsonify({'error': 'forbidden', 'message': message})
22+
response.status_code = 403
23+
return response

api/models/user.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
1+
from werkzeug.security import generate_password_hash, check_password_hash
2+
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
3+
from flask import current_app
4+
15
from .. import db
26

37

48
class User(db.Model):
59
id = db.Column(db.Integer, primary_key=True)
6-
name = db.Column(db.String(32))
10+
username = db.Column(db.String(32))
11+
_password = db.Column(db.String(128))
12+
13+
token = db.Column(db.String(128))
14+
15+
@property
16+
def test(self):
17+
return 'id:{}'.format(self.id)
18+
19+
@property
20+
def password(self):
21+
raise AttributeError('password not readable')
22+
23+
@password.setter
24+
def password(self, password):
25+
self._password = generate_password_hash(password)
26+
27+
def verify_password(self, password):
28+
return check_password_hash(self._password, password)
29+
30+
def generate_auth_token(self, expiration=3600 * 8):
31+
s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration)
32+
33+
return s.dumps({'id': self.id})
34+
35+
@staticmethod
36+
def verify_auth_token(token):
37+
s = Serializer(current_app.config['SECRET_KEY'])
38+
39+
try:
40+
data = s.loads(token)
41+
except:
42+
return None
43+
return User.query.get(data['id'])

api/users/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from flask import Blueprint
2+
from api.app import api
3+
from api.auth_token import token_auth
4+
from api.errors import *
5+
6+
from .resources.users import User
7+
8+
api_user = Blueprint('users', __name__)
9+
10+
api.add_resource(User, '/user')
11+
12+
api.init_app(api_user)
13+
14+
15+
@api_user.before_request
16+
@token_auth.login_required
17+
def before_request():
18+
pass
19+
20+
21+
@api_user.errorhandler(ValidationError)
22+
def validation_error(e):
23+
return bad_request(e.args[0])

0 commit comments

Comments
 (0)