Google için özel kimlik Doğrulaması Bitiş noktası (OAuth2 yerine)Bulut
Süper Google Cloud Endpoints App Engine desteği için heyecanlıyız.
Bu OAuth2 henüz kullanmak ve genellikle kullanıcı adı/parola kimlik doğrulaması ile kullanıcılar değiliz " dedi Google Hesabı yoktur, müşterilerin destekleyebiliriz.
Bizim API biz daha sonra ücretsiz olarak tüm avantajları nedeniyle Bulut Uç Google üzerinden göç etmek istiyorum (Konsol API, İstemci Kitaplıkları, sağlamlık, ...) ama bizim asıl soru
Bulut için özel kimlik doğrulama eklemek için nasıl biz daha önce geçerli bir kullanıcı oturum belirteci mevcut API CSRF için onay bitiş noktası.
ProtoRPC iletileri için oturum bilgileri ve CSRF belirteçleri gibi şeyler ekleyerek olmadan bunu yapmak için zarif bir yolu var mı?
CEVAP
Benim bütün uygulama için webapp2 kimlik Doğrulama sistemi kullanıyorum. Google Bulut kimlik Doğrulaması için bu yeniden denedim ve anladım!
webapp2_extras.auth kullanır webapp2_extras.kimlik doğrulama bilgilerini saklamak için oturumları. Ve bu oturumu 3 farklı biçimlerde depolanabilir: securecookie, veri deposuna veya memcache.
Securecookie kullanıyorum varsayılan biçim. Bu webapp2 auth sistemi GAE uygulama üretim ortamında çalışan bir çok kullanıldığından dolayı yeterince güvenli olduğunu düşünüyorum.
Bu securecookie ben deşifre ve GAE Uç noktalardan yeniden. @Bossylobster Tamam güvenlik tarafına baktığımızda ise söyle. eğer bunu bir güvenlik sorunu (umarım) üretilmesi ama belki de, bilmiyorum.
Benim Apı:
import Cookie
import logging
import endpoints
import os
from google.appengine.ext import ndb
from protorpc import remote
import time
from webapp2_extras.sessions import SessionDict
from web.frankcrm_api_messages import IdContactMsg, FullContactMsg, ContactList, SimpleResponseMsg
from web.models import Contact, User
from webapp2_extras import sessions, securecookie, auth
import config
__author__ = 'Douglas S. Correa'
TOKEN_CONFIG = {
'token_max_age': 86400 * 7 * 3,
'token_new_age': 86400,
'token_cache_age': 3600,
}
SESSION_ATTRIBUTES = ['user_id', 'remember',
'token', 'token_ts', 'cache_ts']
SESSION_SECRET_KEY = '9C3155EFEEB9D9A66A22EDC16AEDA'
@endpoints.api(name='frank', version='v1',
description='FrankCRM API')
class FrankApi(remote.Service):
user = None
token = None
@classmethod
def get_user_from_cookie(cls):
serializer = securecookie.SecureCookieSerializer(SESSION_SECRET_KEY)
cookie_string = os.environ.get('HTTP_COOKIE')
cookie = Cookie.SimpleCookie()
cookie.load(cookie_string)
session = cookie['session'].value
session_name = cookie['session_name'].value
session_name_data = serializer.deserialize('session_name', session_name)
session_dict = SessionDict(cls, data=session_name_data, new=False)
if session_dict:
session_final = dict(zip(SESSION_ATTRIBUTES, session_dict.get('_user')))
_user, _token = cls.validate_token(session_final.get('user_id'), session_final.get('token'),
token_ts=session_final.get('token_ts'))
cls.user = _user
cls.token = _token
@classmethod
def user_to_dict(cls, user):
"""Returns a dictionary based on a user object.
Extra attributes to be retrieved must be set in this module's
configuration.
:param user:
User object: an instance the custom user model.
:returns:
A dictionary with user data.
"""
if not user:
return None
user_dict = dict((a, getattr(user, a)) for a in [])
user_dict['user_id'] = user.get_id()
return user_dict
@classmethod
def get_user_by_auth_token(cls, user_id, token):
"""Returns a user dict based on user_id and auth token.
:param user_id:
User id.
:param token:
Authentication token.
:returns:
A tuple ``(user_dict, token_timestamp)``. Both values can be None.
The token timestamp will be None if the user is invalid or it
is valid but the token requires renewal.
"""
user, ts = User.get_by_auth_token(user_id, token)
return cls.user_to_dict(user), ts
@classmethod
def validate_token(cls, user_id, token, token_ts=None):
"""Validates a token.
Tokens are random strings used to authenticate temporarily. They are
used to validate sessions or service requests.
:param user_id:
User id.
:param token:
Token to be checked.
:param token_ts:
Optional token timestamp used to pre-validate the token age.
:returns:
A tuple ``(user_dict, token)``.
"""
now = int(time.time())
delete = token_ts and ((now - token_ts) > TOKEN_CONFIG['token_max_age'])
create = False
if not delete:
# Try to fetch the user.
user, ts = cls.get_user_by_auth_token(user_id, token)
if user:
# Now validate the real timestamp.
delete = (now - ts) > TOKEN_CONFIG['token_max_age']
create = (now - ts) > TOKEN_CONFIG['token_new_age']
if delete or create or not user:
if delete or create:
# Delete token from db.
User.delete_auth_token(user_id, token)
if delete:
user = None
token = None
return user, token
@endpoints.method(IdContactMsg, ContactList,
path='contact/list', http_method='GET',
name='contact.list')
def list_contacts(self, request):
self.get_user_from_cookie()
if not self.user:
raise endpoints.UnauthorizedException('Invalid token.')
model_list = Contact.query().fetch(20)
contact_list = []
for contact in model_list:
contact_list.append(contact.to_full_contact_message())
return ContactList(contact_list=contact_list)
@endpoints.method(FullContactMsg, IdContactMsg,
path='contact/add', http_method='POST',
name='contact.add')
def add_contact(self, request):
self.get_user_from_cookie()
if not self.user:
raise endpoints.UnauthorizedException('Invalid token.')
new_contact = Contact.put_from_message(request)
logging.info(new_contact.key.id())
return IdContactMsg(id=new_contact.key.id())
@endpoints.method(FullContactMsg, IdContactMsg,
path='contact/update', http_method='POST',
name='contact.update')
def update_contact(self, request):
self.get_user_from_cookie()
if not self.user:
raise endpoints.UnauthorizedException('Invalid token.')
new_contact = Contact.put_from_message(request)
logging.info(new_contact.key.id())
return IdContactMsg(id=new_contact.key.id())
@endpoints.method(IdContactMsg, SimpleResponseMsg,
path='contact/delete', http_method='POST',
name='contact.delete')
def delete_contact(self, request):
self.get_user_from_cookie()
if not self.user:
raise endpoints.UnauthorizedException('Invalid token.')
if request.id:
contact_to_delete_key = ndb.Key(Contact, request.id)
if contact_to_delete_key.get():
contact_to_delete_key.delete()
return SimpleResponseMsg(success=True)
return SimpleResponseMsg(success=False)
APPLICATION = endpoints.api_server([FrankApi],
restricted=False)
V3 API hizmet Uygulamaları ve Google A...
Uygulama *için OAuth2 ile kimlik doğru...
Form tabanlı kimlik doğrulaması için k...
Ayrıca güvenli bir web hizmetine erişi...
node.js kimlik doğrulaması için Kullan...