已经不想写java了,python操作起来不用担心什么服务都搞个100多M,只是网上的资料并不多,写脚本就能提供接口,是不是很轻量?
pip install sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install tornado -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install python-oauth2 -i https://pypi.tuna.tsinghua.edu.cn/simple
服务端定义
from tornado import web, httpserver, ioloop
from controller import OrderHandler,TokenHandler
from oauth2 import Provider
from oauth2.grant import ClientCredentialsGrant,RefreshToken
from oauth2.tokengenerator import Uuid4
from oauth2.store.redisdb import TokenStore
from oauth2.store.memory import ClientStore
from settings import API_CONFIG,ENV,REDIS_CONFIG
def run_app_server():
client_store = ClientStore()
client_store.add_client(client_id=API_CONFIG['sc']['client_id'],client_secret=API_CONFIG['sc']['client_secret'],redirect_uris="")
token_store = TokenStore(host=REDIS_CONFIG[ENV]['host'],port=REDIS_CONFIG[ENV]['port'], db=REDIS_CONFIG[ENV]['db'])
generator = Uuid4()
generator.expires_in = {'client_credentials':API_CONFIG['api']['token']}
provider = Provider(access_token_store=token_store,auth_code_store=token_store,client_store=client_store
,token_generator=generator)
provider.add_grant(ClientCredentialsGrant())
try:
app = web.Application([
(r"/kkd/order/add",OrderHandler),
web.url(provider.authorize_path,TokenHandler,dict(provider=provider)),
web.url(provider.token_path,TokenHandler,dict(provider=provider)),
])
httpServer = httpserver.HTTPServer(app)
httpServer.listen(8000)
ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
ioloop.IOLoop.close()
扩展一下返回参数,这个python-oauth2
写的还是有些粗糙
class TokenHandler(OAuth2Handler):
def post(self):
response = self._dispatch_request()
for name, value in list(response.headers.items()):
self.set_header(name, value)
body = json.loads(response.body)
if 'access_token' in body:
resp = {'success':True,'code':'0000','timestamp':int(str(time.time()*1000).split('.')[0])}
resp['data'] = {
'access_token':body['access_token'],
'token_type':body['token_type'],
'expires_in':10000
}
else:
resp = {'success':False,'code':'0003','msg':'认证失败'}
self.write(json.dumps(resp, ensure_ascii=False))
self.set_status(response.status_code)
再业务中,从redis中获取token
def check_token(self):
'''
检查token
'''
access_token = token_store.fetch_existing_token_of_user(client_id=API_CONFIG['sc']['client_id'],grant_type="client_credentials",user_id=None)
token = self.request.headers.get('Authorization')
if token == 'Bearer '+access_token.token:
return None
else:
return 'token认证失败'
python-oauth2
这个里面是bug的,数据写入到redis中,没有过期时间,改两个地方就可以了
在oauth2.store.redisdb.TokenStore
,过期时间写在数据里面有什么用的,永远不会清楚,除非自己写定时任务
def save_token(self, access_token):
"""
Stores the access token and additional data in redis.
See :class:`oauth2.store.AccessTokenStore`.
"""
self.write(access_token.token, access_token) # edit bj dzm 去掉__dict__
unique_token_key = self._unique_token_key(access_token.client_id,
access_token.grant_type,
access_token.user_id)
self.write(unique_token_key, access_token) # edit bj dzm 去掉__dict__
if access_token.refresh_token is not None:
self.write(access_token.refresh_token, access_token.__dict__)
def write(self, name, data):
cache_key = self._generate_cache_key(name)
self.rs.set(cache_key, json.dumps(data.__dict__),ex=data.expires_in) # edit by dzm
在centos环境下安装python-oauth2
报错
Collecting python-oauth2
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/09/30/fae66a452716f49b69124c9286ba48719ae62014a1f97bcf269c88c0c0d3/python-oauth2-1.1.1.tar.gz (45 kB)
|████████████████████████████████| 45 kB 2.0 MB/s
ERROR: Command errored out with exit status 1:
command: /usr/local/python3/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-reexv8iu/python-oauth2/setup.py'"'"'; __file__='"'"'/tmp/pip-install-reexv8iu/python-oauth2/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-8j99t6z6
cwd: /tmp/pip-install-reexv8iu/python-oauth2/
Complete output (11 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/python3/lib/python3.8/site-packages/setuptools/__init__.py", line 23, in <module>
from setuptools.dist import Distribution
File "/usr/local/python3/lib/python3.8/site-packages/setuptools/dist.py", line 34, in <module>
from setuptools import windows_support
File "/usr/local/python3/lib/python3.8/site-packages/setuptools/windows_support.py", line 2, in <module>
import ctypes
File "/usr/local/python3/lib/python3.8/ctypes/__init__.py", line 7, in <module>
from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
需要yum install libffi-devel -y
,重新安装python