Мне очень нравятся сервисы вроде formsping.me, ask.fm тем, что у каждого пользователя есть своя маленькая страничка (например, ask.fm/popova) — и ты сразу знаешь к кому попал.
Мне и моему другу sborod пришла в голову идея сделать сервис для признаний в любви с похожей механикой:
1. Андрей заходит на сайт, логинясь через ВКонтакте, и вводит ссылку на профиль Марины, которая ему нравится.
2. Ему генерируется собственная страничка howmuchiloveyou.ru/его короткое имя или id номер ВКонтакте, если короткое имя не указано.
3. Он копирует ссылку себе в статус ВКонтакте или на стену.
4. Всем перешедшим по ссылке, кроме Марины, говорят: «Я люблю не тебя». Если заходит Марина, то ей выводится: «Я тебя люблю! Андрей».
Вот такая простая на деле, но сложная для объяснения механика сервиса.
Дело было накануне Дня святого Валентина. У нас было два дня на всё: от проектирования и покупки домена до выкатывания и исправления мелких ошибок, поэтому были выбраны Рельсы.
В статье я вкратце расскажу про основные моменты создания приложения и некоторые особенности интеграции со ВКонтакте.
Поехали!
rails new howmuchiloveyou
Сначала мы прикинули схему путей, которая в итоге стала такой (после картинки — объяснение):
У пользователя есть три варианта захода в приложение:
1. В "/welcome" из поисковых машин. Здесь будет отображаться общая информация о сервисе.
2. В "/show/:id" по чьей-то ссылке. Здесь будет отображаться любит ли тебя пользователь.
3. В "/choose_love", являющимся "/". Здесь залогиненный пользователь может выбрать свою любовь.
Серыми стрелками показаны автоматические редиректы, а зелеными — переходы по ссылкам.
Идем дальше. Создание модели:
rails generate model User vk_id:integer vk_screen_name:string love_id:integer
vk_screen_name — короткое имя ВКонтакте.
love_id — id, понравившегося человека.
Создаем приложение ВКонтакте:
Создаем файл constants.rb в /config/initializers с константами приложения:
# ID приложения
APP_ID = 2800816
# Защищенный ключ
APP_SECRET = "top secret code"
Кладем в /lib библиотеку vk_oauth2.rb, позволяющую делать запросы к API ВКонтакте с помощью OAuth 2.0 (описание):
require 'net/http'
def vk_api_get(domain_name, params)
http = Net::HTTP.new(domain_name, 443)
http.use_ssl = true
res = http.get(params)
ActiveSupport::JSON.decode(res.body)
end
Все приготовления сделаны. Осталось рассказать о самом процессе авторизации через ВКонтакте. Чтобы поставить свою любовь, человеку предлагается залогиниться по ссылке:
<a href='http://oauth.vk.com/authorize?client_id=2800816&scope=friends&redirect_uri=http://howmuchiloveyou.ru/login&response_type=code'>Войти через ВКонтакте</a>
redirect_uri — это адрес, на который человек перенаправится после того, как даст разрешение использовать приложению личную информацию из ВКонтакте. В нашем случае — howmuchiloveyou.ru/login (которому передается параметр code, который используется для получения access_token, который будет использоваться для обращения к API).
Пишем в config/routes.rb:
match 'login' => 'users#login', :as => :login, :via => :get
Рассмотрим функцию login в контроллере users.rb:
def login
# используем функцию из vk_oauth2.rb, чтобы распарсить, полученный JSON:
login_parsed_json = vk_api_get(
"oauth.vk.com",
"/access_token?client_id=#{APP_ID}&" +
"client_secret=#{APP_SECRET}&" +
"code=#{params[:code]}"
)
# проверяем на ошибки:
if login_parsed_json["error"].nil?
@user = User.where(:vk_id => login_parsed_json["user_id"]).first
unless @user
# создание нового юзера
@user = User.new(:vk_id => login_parsed_json["user_id"])
# запрос короткого имени. Если не указано пользователем, то ВКонтакте
# пришлет screen_name в виде "id3455"
@uservk_screen_name = vk_api_get(
"api.vk.com", "/method/getProfiles?uid=#{login_parsed_json["user_id"]}&" +
"fields=screen_name&" +
"access_token=#{session[:access_token]}"
)["response"][0]["screen_name"]
end
@user.save
session[:user_id] = @user.id
session[:access_token] = login_parsed_json["access_token"]
redirect_to root_path
else
render :text => "Ошибка API vk.com: #{login_parsed_json['error']}." +
"Описание: #{login_parsed_json['error_description']}."
end
end
Имеем user_id и access_token в сессии, и теперь можно делать любые запросы к API ВКонтакте.
В итоге.
Как вы поняли, интегрировать ВКонтакте и Rail's проекты достаточно просто. Использовать одни и те же id и короткие имена на разных проектах очень приятно и вам, и пользователям.
Если кому-то интересно узнать подробности, то мы можем выложить исходники и/или расписать шаги более подробно в продолжении.
Спасибо за внимание!
Автор: ivanxo