2015-08-18 2 views
1

Я пытаюсь обернуть голову вокруг реализации надлежащей аутентификации в SPA с бэкэнд.Аутентификация SPA (Ember) vs backend

Я смотрю на 2 разных фронтэндах: 1. SPA с ember.js 2. мобильных приложений

Я пытаюсь создать бэкенд, который служит одновременно (либо в Rails или Python, не решили все же). Я хочу, чтобы аутентификация выполнялась либо через Google, либо в Facebook, т. Е. Мне не нужно поддерживать отдельную регистрацию пользователей, но мне все равно нужно поддерживать пользователей, поскольку я хочу иметь возможность «объединить» аутентификации от Google и Facebook в конце день. Я также хочу, чтобы бэкэнд был полностью без гражданства по причинам масштабируемости. Также я бы предпочел сделать как можно больше на стороне клиента, чтобы освободить нагрузку от бэкэнд.

Мои вопросы заключаются в следующем:

  1. Я запросить маркер аутентификации в SPA или в мобильном приложении. Должен ли я преобразовать это в токен доступа на стороне сервера или на стороне клиента? Мне нужно разрешить запросы на бэкэнд, и мне нужно сделать это без гражданства. Моя идея состояла в том, чтобы сделать все на стороне интерфейса и передать маркер доступа каждому запросу на бэкэнд, чтобы его также проверяли на стороне сервера, но я не уверен, что это эффективный подход.

  2. Я хочу, чтобы иметь возможность объединять аутентификации Google и Facebook, каковы лучшие практики для этого? Я планировал поддерживать реестр пользователей на стороне сервера и проверять адреса электронной почты, исходящие из авторизованных запросов на бэкэнд, и объединять пользователей, если есть соответствие по адресам электронной почты. Каковы наилучшие методы и существуют ли библиотеки, поддерживающие это в Python/Flask или Ruby или Rails?

Спасибо!

ответ

1

Я не совсем уверен, что вы подразумеваете под «без гражданства». Вам, очевидно, нужна база данных для хранения данных пользователя (в противном случае вам вообще не нужен бэкэнд). Таким образом, база данных - это ваше состояние. Протокол HTTP по определению не имеет апатридов, поэтому вы не можете быть очень сдержанным с помощью других средств, кроме хранения данных в БД.

Я попрошу токен аутентификации в SPA или в мобильном приложении. Должен ли я преобразовать это в токен доступа на стороне сервера или на стороне клиента?

Если вам не нужно использовать Google/Facebook от имени пользователей (и вашей редакции предполагает, что вы не), вам не нужно конвертировать auth_token в server_token вообще.

Вам просто нужно позвонить в Google/Facebook API (у Ruby есть библиотеки для обоих, так что это в основном одна строка кода) и получить идентификатор пользователя социальной сети и электронную почту пользователя.

Затем вы сохраняете этот ID + адрес электронной почты в своей базе данных и даете вашему внутренний серверный токен (только случайная строка) вашему пользователю. Вы сами генерируете эту строку и передаете ее клиенту.

Если пользователь входит в систему с другого устройства (т.он дает вам auth_token, с помощью которого вы узнаете, что адрес электронной почты пользователя принадлежит одному из уже зарегистрированных пользователей), вы либо возвращаете существующий внутренний токен, либо генерируете новый, и привязываете его к существующему пользователю (в зависимости от того, что вы определяете по приоритетам - высокая безопасность простота внедрения/обслуживания).

Я хочу, чтобы иметь возможность объединять аутентификации Google и Facebook, каковы лучшие практики для этого?

Facebook гарантирует что если это дает пользователю по электронной почте, то это обеспечивается что, что электронная почта относится к данному пользователю. Google, очевидно, делает то же самое. Поэтому вы просто объединяете их по электронной почте.

Для этого вам не нужны специальные библиотеки, так как это простая операция с вашим кодом на выбранном вами языке.

Я бы организовать все вещи в базе данных следующим образом: таблицы

Пользователи

id 
email 

авторизаций стол

user_id 
email 
social_uid  # facebook number or google email 
social_network # string, 'facebook' or 'google' 
device   # user agent, e.g. 'android' 
ip    # last login IP address 
token   # internal token 

Когда пользователь входит в систему, проверки подлинности объект создается. Если у пользователя нет такого сообщения, пользователь будет создан. Если есть пользователь, он привязывается к объекту аутентификации (как через поле user_id).

Заметка о лексемах

Если вы планируете взаимодействовать с социальной сетью доступа (другими способами, чем просто аутентифицируется пользователь), вы должны обменять auth_token для server_token. server_token - это «постоянный» (ну, вид) токен авторизации для доступа к API-интерфейсам социальной сети, тогда как auth_token имеет очень ограниченный срок службы (и некоторые вызовы API могут быть ограничены, если вы не получили server_token).

По-прежнему может исчезнуть server_token (или пользователь может вспомнить свой доступ для вашего приложения), поэтому вам следует планировать заранее, чтобы обнаружить эту ситуацию и повторно приобрести токен/авторизацию, если это необходимо.

Ключевые моменты при создании Rails приложение

В Rails, для создания таблиц, вам нужно написать migrations:

gem install rails 
rails new my_project 
cd my_project 
rails generate migration create_users 
rails generate migration create_authentications 

Это создаст структуру папок проекта и два файла миграции, которая вам нужно заполнить:

# db/migrate/xxx_create_users.rb 

def change 
    create_table :users do |t| 
    t.string :email 
    end 
end 

# db/migrate/xxx_create_authentications.rb 

def change 
    create_table :authentications do |t| 
    t.integer :user_id 
    t.index :user_id 

    t.string :social_uid 
    # etc., all other fields 
    # ... 
    end 
end 

Затем вы создаете "models «для обработки манипуляции связанные с базой данных:

# app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :authentications 
end 

# app/models/authentication.rb 
class Authentication < ActiveRecord::Base 
    belongs_to :user 
    before_create :set_token 
    after_commit :create_user_if_needed 

    private 

    def set_token 
    self.token = SecureRandom.urlsafe_base64(20) 
    end 

    def create_user_if_needed 
    unless self.user.present? 
     self.user.create(email: self.email) 
    end 
    end 
end 

И писать» controller "для обработки запроса от пользователя с помощью одного метода внутри него:

# app/controllers/login_controller.rb 
class LoginController < ActionController 
    # Login via Facebook method 
    def facebook 
    token = params.require(:auth_token) 

    # we will use Koala gem 
    profile = Koala::Facebook::API.new(token).get_object('me', fields: 'email') 

    # user is created automatically by model 
    authentication = Authentication.where(social_network: 'facebook', social_uid: profile['id'], email: profile['email']).first_or_create 
    authentication.update(...) # set ip and device 
    render json: {token: authentication.token} 
    end 

    # This one you'll have to write yourself as an exercise :) 
    def google 
    end 
end 

Конечно, вам нужно настроить routes для действия:

# config/routes.rb 

post "login/:action", controller: 'login' 

и добавить Koala (или то, что вы будете использовать для управления внешнего API, для которых уже существуют хорошие пакеты Ruby) для Gemfile:

# Gemfile 
gem 'koala' 

Затем в терминале выполните команду:

bundle install 
rails server 

И ваше приложение и работает. Ну, сначала вам нужно настроить приложения Facebook и Google, получить ключи от разработчика и разрешить localhost принять auth_tokens.

В принципе, все.

+0

Спасибо за очень исчерпывающий ответ, это понятно и понятно. Как изменится этот поток, если мне нужно будет взаимодействовать от имени моих пользователей на Facebook? Я также немного не определился, если я должен сделать это взаимодействие непосредственно из SPA/мобильного приложения (в этом случае я предполагаю, что мне нужно получить там токен доступа) или через серверную базу (там я бы предположил, что мне нужно создать маркер доступа на стороне сервера, а мобильный/SPA вообще не должен знать об этом). – abali

+1

Если у вас несколько клиентов (и вы говорите, что у вас есть как минимум два), это хорошая идея для реализации социальных сетевых взаимодействий на сервере - вам нужно будет сделать это один раз (вместо одного времени для каждого клиента). Какие изменения вы должны приобрести (обменять на 'auth_token') и хранить' server_token', а затем использовать его для доступа к API социальной сети. – EugZol

+0

Спасибо, это действительно имеет смысл. Я предполагаю, что в этом случае лучше всего хранить токен доступа только на стороне сервера и продолжать авторизацию между клиентом и сервером на основе самогенерированного внутреннего токена, то есть я должен проверить все запросы на бэкэнд, если они содержат действительный токен или нет, а если нет, отклоняйте запрос и заставляйте клиента повторно аутентифицироваться с помощью FB/Google. – abali

Смежные вопросы