Rails 使用 Rails 构建 API 实践
我是来鼓吹使用 Rails 写 API 的。
原文在此:https://labs.kollegorna.se/blog/2015/04/build-an-api-now/
原文有一个很大的缺陷就是读者无法按照它的步骤一步一步的去实现一个可以运行的 demo, 这对经验丰富的开发 者可能不算是一个问题,但是对刚刚接触这方面知识的新手来说却是一个很大的遗憾,软件开发方面的知识重在 实践,只有动手做了,才能对知识掌握地更加牢靠,才能更好地在工作中去使用这些知识,所以我对原文的内容 做了一些补充修整,以期能够让读者边读边思考边实践。
原文的 demo 是一个类微博应用,为简单起见我们只使用 User 和 Micropost 模型,并且我们不使用 ActiveModel::Serializer, 而是使用 Jbuilder 作为 json 模版。
首先建立一个项目:build-an-api-rails-demo
$rails new build-an-api-rails-demo
加入第一个 API resource
BaseController
生成控制器:
# 我们不需要生成资源文件
$bundle exe rails g controller api/v1/base --no-assets
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
# disable the CSRF token
protect_from_forgery with: :null_session
# disable cookies (no set-cookies header in response)
before_action :destroy_session
# disable the CSRF token
skip_before_action :verify_authenticity_token
def destroy_session
request.session_options[:skip] = true
end
end
在 BaseController 里我们禁止了 CSRF token 和 cookies
配置路由:
config/routes.rb,
namespace :api do
namespace :v1 do
resources :users, only:[:index, :create, :show, :update, :destroy]
# 原文有 microposts, 我们现在把它注释掉
# resources :microposts, only: [:index, :create, :show, :update, :destroy]
end
end
Api::V1::UsersController
生成控制器:
# 我们不需要生成资源文件
$bundle exe rails g controller api/v1/users --no-assets
app/controllers/api/v1/users_controller.rb,
class Api::V1::UsersController < Api::V1::BaseController
def show
@user = User.find(params[:id])
# 原文使用 Api::V1::UserSerializer
# 我们现在使用 app/views/api/v1/users/show.json.jbuilder
# render(json: Api::V1::UserSerializer.new(user).to_json)
end
end
app/views/api/v1/users/show.json.jbuilder,
json.user do
json.(@user, :id, :email, :name, :activated, :admin, :created_at, :updated_at)
end
User 模型和 users 表
$bundle exe rails g model User
app/models/user.rb,
class User < ActiveRecord::Base
end
db/migrate/20150502072954_create_users.rb,
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :name
t.datetime :activated
t.boolean :admin, default:false
t.timestamps null:false
end
end
end
数据迁移:
$bundle exe rake db:migrate
种子数据:
db/seeds.rb,
users = User.create([
{
email:'[email protected]',
name:'test-user-00',
activated:DateTime.now,
admin:false
},
{
email:'[email protected]',
name:'test-user-01',
activated:DateTime.now,
admin:false
}
])
创建种子数据:
$ bundle exe rake db:seed
现在我们可以测试一下 api 是否正常工作,我们可以先查看下相关 api 的路由,
$bundle exe rake routes
输出:
Prefix Verb URI Pattern Controller#Action
api_v1_users GET /api/v1/users(.:format) api/v1/users#index
POST /api/v1/users(.:format) api/v1/users#create
api_v1_user GET /api/v1/users/:id(.:format) api/v1/users#show
PATCH /api/v1/users/:id(.:format) api/v1/users#update
PUT /api/v1/users/:id(.:format) api/v1/users#update
DELETE /api/v1/users/:id(.:format) api/v1/users#destroy
启动 rails 服务,
$bundle exe rails s
使用 curl 请求 api,
$curl -i http://localhost:3000/api/v1/users/1.json
{"user":{"id":1,"email":"[email protected]","name":"test-user-00","activated":"2015-05-02T07:47:14.697Z","admin":false,"created_at":"2015-05-02T07:47:14.708Z","updated_at":"2015-05-02T07:47:14.708Z"}}
恭喜,我们的 api 工作正常!
增加认证 (Authentication)
认证的过程是这样的:用户把她的用户名和密码通过 HTTP POST 请求发送到我们的 API (在这里我们使用 sessions 端点来处理这个请求), 如果用户名和密码匹配,我们 会把 token 发送给用户。这个 token 就是用来证明用户身份的凭证。然后在以后的每个请求中,我们都通过这个 token 来查找用户,如果没有找到用户则返回 401 错误。
给 User 模型增加 authentication_token 属性
$bundle exe rails g migration add_authentication_token_to_users
db/migrate/20150502123451_add_authentication_token_to_users.rb
class AddAuthenticationTokenToUsers < ActiveRecord::Migration
def change
add_column :users, :authentication_token, :string
end
end
$bundle exe rake db:migrate
生成 authentication_token
app/models/user.rb,
class User < ActiveRecord::Base
+ before_create :generate_authentication_token
+ def generate_authentication_token
+ loop do
+ self.authentication_token = SecureRandom.base64(64)
+ break if !User.find_by(authentication_token:authentication_token)
+ end
+ end
+ def reset_auth_token!
+ generate_authentication_token
+ save
+ end
end
和原文相比,我给 User 模型增加了一个 reset_auth_token!
方法,我这样做的理由主要有以下几点:
- 我觉得需要有一个方法帮助用户重置 authentication token, 而不仅仅是在创建用户时生成 authenticeation token;
- 如果用户的 token 被泄漏了,我们可以通过
reset_auth_token!
方法方便地重置用户 token;
sessions endpoint
生成 sessions 控制器,
# 我们不需要生成资源文件
$bundle exe rails g controller api/v1/sessions --no-assets
create app/controllers/api/v1/sessions_controller.rb
invoke erb
create app/views/api/v1/sessions
invoke test_unit
create test/controllers/api/v1/sessions_controller_test.rb
invoke helper
create app/helpers/api/v1/sessions_helper.rb
invoke test_unit
app/controllers/api/v1/sessions_controller.rb,
class Api::V1::SessionsController < Api::V1::BaseController
def create
@user = User.find_by(email:create_params[:email])
if @user && @user.authenticate(create_params[:password])
self.current_user = @user
# 我们使用 jbuilder
# render(
# json: Api::V1::SessionSerializer.new(user, root: false).to_json,
# status: 201
# )
else
return api_error(status:401)
end
end
private
def create_params
params.require(:user).permit(:email, :password)
end
end
现在我们还需要做一些原文没有提到的工作:
- 给 User 模型增加和 password 相关的属性;
- 给数据库中已存在的测试用户增加密码和 authentication token;
- 实现和 current_user 相关的方法;
- 实现 app/views/api/v1/sessions/create.json.jbuilder;
- 配置和 sessions 相关的路由;
给 User 模型增加和 password 相关的属性
在 Gemfile 里将 gem 'bcrypt'
这一行的注释取消
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'
app/models/user.rb,
class User < ActiveRecord::Base
+ has_secure_password
end
给 User 模型增加 password_digest 属性,
$bundle exe rails g migration add_password_digest_to_users
db/migrate/20150502134614_add_password_digest_to_users.rb,
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
$bundle install
$bundle exe rake db:migrate
给数据库中已存在的测试用户增加密码和 authentication token
这个任务可以在 rails console 下完成,
首先启动 rails console,
$bundle exe rails c
然后在 rails console 里执行,
User.all.each {|user|
user.password = '123123'
user.reset_auth_token!
}
实现和 current_user 相关的方法
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
+ attr_accessor :current_user
end
实现 app/views/api/v1/sessions/create.json.jbuilder
app/views/api/v1/sessions/create.json.jbuilder,
json.session do
json.(@user, :id, :name, :admin)
json.token @user.authentication_token
end
配置和 sessions 相关的路由
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
+ resources :sessions, only:[:create]
end
end
end
现在我们做一个测试看是否能够顺利地拿到用户的 token, 我们使用下面的用户作为测试用户:
{
email:'[email protected]',
name:'test-user-00'
}
$curl -i -X POST -d "user[email][email protected]&user[password]=123123" http://localhost:3000/api/v1/sessions.json
{"session":{"id":1,"name":"test-user-00","admin":false,"token":"izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w=="}}
我们顺利地拿到了 token。
我们再做一个验证失败的测试。
我们使用一个错误的密码:fakepwd
curl -i -X POST -d "user[email][email protected]&user[password]=fakepwd" http://localhost:3000/api/v1/sessions.json
糟糕系统出错了:
NoMethodError (undefined method `api_error' for #<Api::V1::SessionsController:0x007fead422c178>):
app/controllers/api/v1/sessions_controller.rb:14:in `create'
原来我们没有实现 api_error 这个方法,那我们现在就实现 api_error 这个方法。
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
+ def api_error(opts = {})
+ render nothing:true, status:opts[:status]
+ end
end
继续测试:
curl -i -X POST -d "user[email][email protected]&user[password]=fakepwd" http://localhost:3000/api/v1/sessions
HTTP/1.1 401 Unauthorized
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/plain; charset=utf-8
Cache-Control: no-cache
X-Request-Id: a5349b47-d756-4830-84f8-0653577f936d
X-Runtime: 0.319768
Server: WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Date: Sat, 02 May 2015 14:41:55 GMT
Content-Length: 0
Connection: Keep-Alive
此时服务器返回了 401 Unauthorized
Authenticate User
在前面的测试中,我们已经成功地拿到了用户的 token, 那么现在我们把 token 和 email 发给 API
看能否成功识别出用户。
首先在 Api::V1::BaseController
里实现 authenticate_user!
方法:
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
+ def authenticate_user!
+ token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
+ user_email = options.blank?? nil : options[:email]
+ user = user_email && User.find_by(email:user_email)
+ if user && ActiveSupport::SecurityUtils.secure_compare(user.authentication_token, token)
+ self.current_user = user
+ else
+ return unauthenticated!
+ end
+ end
end
ActionController::HttpAuthentication::Token
是 rails 自带的方法,可以参考 rails 文档 了解其详情。
当我们通过 user_email 拿到 user 后,通过 ActiveSupport::SecurityUtils.secure_compare
对 user.authentication_token 和从请求头里取到的 token 进行比较,如果匹配则认证成功,否则返回
unauthenticated!
。这里使用了 secure_compare
对字符串进行比较,是为了防止时序攻击 (timing attack)
我们构造一个测试用例,这个测试用例包括以下一些步骤:
- 用户登录成功,服务端返回其 email, token 等数据
- 用户请求 API 更新其 name, 用户发送的 token 合法,更新成功
- 用户请求 API 更新其 name, 用户发送的 token 非法,更新失败
为了让用户能够更新其 name, 我们需要实现 user update API, 并且加入 before_action :authenticate_user!, only: [:update]
app/controllers/api/v1/users_controller.rb,
class Api::V1::UsersController < Api::V1::BaseController
+ before_action :authenticate_user!, only:[:update]
+ def update
+ @user = User.find(params[:id])
+ @user.update_attributes(update_params)
+ end
+ private
+ def update_params
+ params.require(:user).permit(:name)
+ end
end
app/views/api/v1/users/update.json.jbuilder,
json.user do
json.(@user, :id, :name)
end
现在我们进行测试,测试用户是:
{
id:1,
email:'[email protected]',
name:'test-user-00',
authentication_token:'izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w=='
}
$curl -i -X PUT -d "user[name]=gg-user" \
--header "Authorization: Token token=izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w==,\[email protected]" \
http://localhost:3000//api/v1/users/1
{"user":{"id":1,"name":"gg-user"}}
我们看到 user name 已经成功更新为 gg-user。
读者们请注意:你们自己测试时需要将 token 换为你们自己生成的 token。
我们使用一个非法的 token 去请求 API, 看看会发生什么状况。
curl -i -X PUT -d "user[name]=bb-user" \
--header "Authorization: Token token=invalid token,\[email protected]" \
http://localhost:3000//api/v1/users/1
服务器出现错误:
NoMethodError (undefined method `unauthenticated!' for #<Api::V1::UsersController:0x007fead6108d80>)
接下来我们实现 unauthenticated!
方法。
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
+ def unauthenticated!
+ api_error(status:401)
+ end
end
继续上面的测试:
curl -i -X PUT -d "user[name]=bb-user" \
--header "Authorization: Token token=invalid token,\[email protected]" \
http://localhost:3000//api/v1/users/1
HTTP/1.1 401 Unauthorized
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/plain; charset=utf-8
Cache-Control: no-cache
X-Request-Id: 8cf07968-1fd0-4041-866a-ddea49af11d3
X-Runtime: 0.005578
Server: WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Date: Sun, 03 May 2015 05:51:52 GMT
Content-Length: 0
Connection: Keep-Alive
服务器返回 401 Unauthorized, 并且 user name 没有被更新。
增加授权 (Authorization)
上面的测试有个问题,就是当前登录的用户可以把其他用户的 name 更新,这个应该是不被允许的,所以我们 还需要增加一个权限认证的机制。在这里我们使用 Pundit 来 实现权限认证。
安装 pundit
Gemfile,
+ gem 'pundit'
$bundle install
app/controllers/api/v1/base_controller.rb,
class Api::V1::BaseController < ApplicationController
+ include Pundit
end
$bundle exe rails g pundit:install
create app/policies/application_policy.rb
将 policies 目录放到 rails 的自动加载路径中:
config/application.rb,
module BuildAnApiRailsDemo
class Application < Rails::Application
+ config.autoload_paths << Rails.root.join('app/policies')
end
end
创建和 user 相关的权限机制
app/policies/user_policy.rb,
class UserPolicy < ApplicationPolicy
def show?
return true
end
def create?
return true
end
def update?
return true if user.admin?
return true if record.id == user.id
end
def destroy?
return true if user.admin?
return true if record.id == user.id
end
class Scope < ApplicationPolicy::Scope
def resolve
scope.all
end
end
end
使用 UserPolicy
app/controllers/api/v1/users_controller.rb,
class Api::V1::UsersController < Api::V1::BaseController
def update
@user = User.find(params[:id])
+ return api_error(status:403) if !UserPolicy.new(current_user, @user).update?
@user.update_attributes(update_params)
end
end
测试:
$curl -i -X PUT -d "user[name]=gg-user" \
--header "Authorization: Token token=izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w==,\[email protected]" \
http://localhost:3000//api/v1/users/2.json
HTTP/1.1 403 Forbidden
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
注意我们测试的 url 地址是 http://localhost:3000//api/v1/users/2, 也就是说我们在更新 id 为 2 的那个用户的 name。此时服务器返回的是 403 Forbidden。
pundit 提供了更简便的 authorize
方法为我们做权限认证的工作。
class Api::V1::UsersController < Api::V1::BaseController
def update
@user = User.find(params[:id])
# return api_error(status: 403) if !UserPolicy.new(current_user, @user).update?
+ authorize @user, :update?
@user.update_attributes(update_params)
end
end
测试:
$curl -i -X PUT -d "user[name]=gg-user" \
--header "Authorization: Token token=izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w==,\[email protected]" \
http://localhost:3000//api/v1/users/2.json
此时服务器报 Pundit::NotAuthorizedError 错误,
Pundit::NotAuthorizedError (not allowed to update?
我们可以使用 rescue_from
捕捉 Pundit::NotAuthorizedError
这类异常。
class Api::V1::BaseController < ApplicationController
include Pundit
+ rescue_from Pundit::NotAuthorizedError, with: :deny_access
+ def deny_access
+ api_error(status:403)
+ end
end
测试:
$curl -i -X PUT -d "user[name]=gg-user" \
--header "Authorization: Token token=izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w==,\[email protected]" \
http://localhost:3000//api/v1/users/2
HTTP/1.1 403 Forbidden
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/plain; charset=utf-8
这次服务器直接返回 403 Forbidden
分页
我们现在要实现一个展示用户发的微博的 API, 如果用户的微博数量很多,那么我们应该用上分页。
建立 Micropost 模型
$bundle exe rails g model Micropost
db/migrate/20150503131743_create_microposts.rb,
class CreateMicroposts < ActiveRecord::Migration
def change
create_table :microposts do |t|
t.string :title
t.text :content
t.integer :user_id
t.timestamps null:false
end
end
end
执行:
$bundle exe rake db:migrate
为 id 为 1 的用户创建 100 条微博纪录:
lib/tasks/data.rake,
namespace :data do
task :create_microposts => [:environment] do
user = User.find(1)
100.times do |i|
Micropost.create(user_id:user.id, title:"title-#{i}", content:"content-#{i}")
end
end
end
执行:
$bundle exe rake data:create_microposts
Api::V1::MicropostsController
执行:
$bundle exe rails g controller api/v1/microposts --no-assets
配置路由:
config/routes.rb,
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
+ scope path:'/user/:user_id' do
+ resources :microposts, only:[:index]
+ end
end
end
end
此时和 microposts 相关的路由如下:
api_v1_microposts GET /api/v1/user/:user_id/microposts(.:format) api/v1/microposts#index
我们使用 kaminari 这个 gem 进行分页。
安装 kaminari,
Gemfile
+ gem 'kaminari'
执行:
$ bundle install
app/models/user.rb
class User < ActiveRecord::Base
+ has_many :microposts
end
app/controllers/api/v1/microposts_controller.rb
class Api::V1::MicropostsController < Api::V1::BaseController
+ def index
+ user = User.find(params[:user_id])
+ @microposts = paginate(user.microposts)
+ end
end
app/controllers/api/v1/base_controller.rb
class Api::V1::BaseController < ApplicationController
def paginate(resource)
resource = resource.page(params[:page] || 1)
if params[:per_page]
resource = resource.per(params[:per_page])
end
return resource
end
end
app/helpers/application_helper.rb
module ApplicationHelper
+ def paginate_meta_attributes(json, object)
+ json.(object,
+ :current_page,
+ :next_page,
+ :prev_page,
+ :total_pages,
+ :total_count)
+ end
end
app/views/api/v1/microposts/index.json.jbuilder,
json.paginate_meta do
paginate_meta_attributes(json, @microposts)
end
json.microposts do
json.array! @microposts do |micropost|
json.(micropost, :id, :title, :content)
end
end
测试:
$curl -i -X GET http://localhost:3000/api/v1/user/1/microposts.json?per_page=3
{
"paginate_meta": {
"current_page":1,
"next_page":2,
"prev_page":null,
"total_pages":34,
"total_count":100
},
"microposts":[
{"id":1,"title":"title-0","content":"content-0"},
{"id":2,"title":"title-1","content":"content-1"},
{"id":3,"title":"title-2","content":"content-2"}
]
}
API 调用频率限制 (Rate Limit)
我们使用 redis-throttle 来实现这个功能。
Gemfile,
gem 'redis-throttle', git:'git://github.com/andreareginato/redis-throttle.git'
执行,
$bundle install
集成到 Rails 中:
config/application.rb,
# At the top of config/application.rb
+ require 'rack/redis_throttle'
class Application < Rails::Application
# Limit the daily number of requests to 3
# 为了测试我们把 limit 设置为 3
+ config.middleware.use Rack::RedisThrottle::Daily, max:3
end
我们开始测试,请求 http://localhost:3000/api/v1/users/1 4 次看会出现什么结果。
前面 3 次请求一切正常,
curl -i http://localhost:3000/api/v1/users/1
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
X-Ratelimit-Limit: 3
X-Ratelimit-Remaining: 0
Etag: W/"eb58510a43ebc583cf61de35b6d20093"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: bbe7437b-ba6e-4cfd-a4ef-49eec4c611fd
X-Runtime: 0.014384
Server: WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Date: Thu, 07 May 2015 13:03:31 GMT
Content-Length: 199
Connection: Keep-Alive
{"user":{"id":1,"email":"[email protected]","name":"gg-user","activated":"2015-05-02T07:47:14.697Z","admin":false,"created_at":"2015-05-02T07:47:14.708Z","updated_at":"2015-05-03T05:40:24.931Z"}}
我们注意服务器返回的两个响应头:X-Ratelimit-Limit 和 X-Ratelimit-Remaining,
X-Ratelimit-Limit 的值一直为 3,表示请求的限制值,
而 X-Ratelimit-Remaining 每请求一次,其值会减 1,直到为 0。
第 4 次请求出现 403 Forbidden, 这说明 redis-throttle 起到了其应有的作用。
curl -i http://localhost:3000/api/v1/users/1
HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
Cache-Control: no-cache
X-Request-Id: fd646f00-a6a8-411d-b5e4-24856c63b078
X-Runtime: 0.002375
Server: WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Date: Thu, 07 May 2015 13:03:33 GMT
Content-Length: 35
Connection: Keep-Alive
403 Forbidden (Rate Limit Exceeded)
redis-throttle 的 redis 连接默认是 redis://localhost:6379/0, 你也可以通过设置环境变量
ENV['REDIS_RATE_LIMIT_URL']
来改变 redis-throttle 的 redis 连接。
CORS
CORS 是 Cross Origin Resource Sharing 的缩写。简单地说 CORS 可以允许其他域名的网页通过 AJAX 请求你的 API。
我们可以使用 rack-cors
gem 来帮助我们的 API 实现 CORS。
Gemfile,
+ gem 'rack-cors'
config/application.rb,
module BuildAnApiRailsDemo
class Application < Rails::Application
+ config.middleware.insert_before 0, "Rack::Cors" do
+ allow do
+ origins '*'
+ resource '*', :headers => :any, :methods => [:get, :post, :put, :patch, :delete, :options, :head]
+ end
+ end
end
end
Version 2 API
随着我们的业务发展,我们的 API 需要做较大的改变,同时我们需要保持 Version 1 API, 所以我们 开始开发 Version 2 API。
routes
config/routes.rb,
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only:[:index, :create, :show, :update, :destroy]
# resources :microposts, only: [:index, :create, :show, :update, :destroy]
resources :sessions, only:[:create]
scope path:'/user/:user_id' do
resources :microposts, only:[:index]
end
end
+ namespace :v2 do
+ resources :users, only:[:index, :create, :show, :update, :destroy]
+ resources :sessions, only:[:create]
+ scope path:'/user/:user_id' do
+ resources :microposts, only:[:index]
+ end
+ end
end
end
controller
生成 API::V2::UsersController, 其他控制器的生成类似
$bundle exe rails g controller api/v2/users --no-assets
app/controllers/api/v2/users_controller.rb,
class Api::V2::UsersController < Api::V1::UsersController
def show
@user = User.find(params[:id])
end
end
app/vies/api/v2/users/show.json.jbuilder,
json.user do
json.(@user, :id, :email, :name, :activated, :admin, :created_at, :updated_at)
end
测试:
$curl -i http://localhost:3000/api/v2/users/1.json
{"user":{"id":1,"email":"[email protected]","name":"gg-user","activated":"2015-05-02T07:47:14.697Z","admin":false,"created_at":"2015-05-02T07:47:14.708Z","updated_at":"2015-05-03T05:40:24.931Z"}}%
文档
原文提到了下面的几种文档工具:
和原文一样,我也喜欢使用 slate 作为文档工具。
将 slate 集成到项目中
创建 docs 目录,
$mkdirapp/docs
集成 slate,
$cdapp/docs
$git clone [email protected]:tripit/slate.git
$rm -rf slate/.git
$cdslate
$bundle install
配置构建目录,app/docs/slate/config.rb
+ set :build_dir, '../../../public/docs/'
现在我们开始编写获取用户信息这个 API 的文档。
app/docs/slate/source/index.md,
---
title: API Reference
language_tabs:
- ruby
toc_footers:
- <a href='http://github.com/tripit/slate'>Documentation Powered by Slate</a>
includes:
- errors
search: true
---
# 介绍
API 文档
# 获取用户信息
## V1
## HTTP 请求
`GET http://my-site/api/v1/users/<id>`
## 请求参数
参数名 | 是否必需 | 描述
-----| --------| -------
id | 是 | 用户 id|
## 响应
\```json
{
"user":
{
"id":1,
"email":"[email protected]",
"name":"test-user-00",
"activated":"2015-05-02T07:47:14.697Z",
"admin":false,
"created_at":"2015-05-02T07:47:14.708Z",
"updated_at":"2015-05-02T07:47:14.708Z"
}
}
\```
注意:index.md 范例里的 json 代码语法高亮部分有转义字符,直接复制可能没法看到语法高亮效果,在实际使用时需要将 ``` 前面的 '\' 符号去掉。
build 脚本
docs_build.sh,
#!/bin/bash
cdapp/docs/slate
bundle execmiddleman build --clean
build docs,
$chmod +x docs_build.sh
$./docs_build.sh
可以通过 http://localhost:3000/docs/index.html
访问文档

给 API 文档添加访问控制
配置路由:
routes.rb,
+ get '/docs/index', to:'docs#index'
建立相关控制器:
$bundle exe rails g controller docs
app/controllers/docs_controller.rb,
class DocsController < ApplicationController
USER_NAME, PASSWORD = 'doc_reader', '123123'
before_filter :basic_authenticate
layout false
def index
end
private
def basic_authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == USER_NAME && password == PASSWORD
end
end
end
同时我们需要把 public/docs/index.html 文件转移到 app/views/docs/ 目录下面,我们
可以更改 docs_build.sh 脚本,注意 docs_build.sh 应该放在项目的根目录下,比如:/path/to/build-an-api-rails-demo/docs_build.sh,
#!/bin/bash
app_dir=`pwd`
cd $app_dir/app/docs/slate
bundle execmiddleman build --clean
cd $app_dir
mv $app_dir/public/docs/index.html $app_dir/app/views/docs
重新 build 文档,
$./docs_build.sh
浏览器访问 http://localhost:3000/docs/index.html,

提示需要输入用户名和密码,我们输入正确的用户名 (doc_reader) 和密码 (123123) 后就可以正常访问文档了,
项目代码
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
buy cialis with american express: Tadal Access - where to buy cialis over the counter
is there a generic cialis available TadalAccess reddit cialis
buy cialis generic online 10 mg best place to buy generic cialis online or buy tadalafil no prescription
http://images.google.ee/url?q=https://tadalaccess.com cialis generic cost
cialis 20mg review cialis or levitra and cheap cialis for sale cialis brand no prescription 365
cialis street price: TadalAccess - vardenafil vs tadalafil
tadalafil tablets 40 mg cialis 5 mg for sale or cialis pills for sale
https://www.google.co.bw/url?sa=t&url=https://tadalaccess.com mint pharmaceuticals tadalafil
cialis not working first time tadalafil and sildenafil taken together and cialis from canadian pharmacy registerd cialis efectos secundarios
https://tadalaccess.com/# what does cialis cost
cialis savings card: cialis for pulmonary hypertension - cialis when to take
cialis 5mg best price [url=https://tadalaccess.com/#]TadalAccess[/url] cialis and cocaine
cialis contraindications: Tadal Access - canadian pharmacy ezzz cialis
cialis back pain cialis at canadian pharmacy or cialis free sample
https://maps.google.com.au/url?sa=t&url=https://tadalaccess.com cialis soft
tadalafil ingredients canada pharmacy cialis and cialis tadalafil 5mg once a day cialis liquid for sale
https://tadalaccess.com/# cialis generic online
cialis pills pictures: TadalAccess - tadalafil online canadian pharmacy
does medicare cover cialis: Tadal Access - tadalafil eli lilly
cialis payment with paypal cialis over the counter natural alternative to cialis
cialis purchase cialis free samples or cialis insurance coverage
http://cse.google.sm/url?sa=i&url=https://tadalaccess.com tadalafil tablets side effects
cialis 40 mg reviews buy cialis by paypal and prices cialis what are the side effect of cialis
cialis coupon free trial where can i buy cialis online in australia or generic cialis vs brand cialis reviews
http://101.43.178.182/sell/email.asp?d=tadalaccess.com&on=tb cialis for daily use dosage
when does the cialis patent expire generic cialis 20 mg from india and cialis milligrams walgreen cialis price
https://tadalaccess.com/# cialis canada over the counter
comprar tadalafil 40 mg en walmart sin receta houston texas: TadalAccess - cialis difficulty ejaculating
generic cialis tadalafil 20 mg from india: Tadal Access - buy cialis online safely
canada drug cialis Tadal Access cialis precio
vidalista 20 tadalafil tablets is tadalafil the same as cialis or how long before sex should i take cialis
https://www.google.co.uz/url?sa=t&url=https://tadalaccess.com taking cialis
cialis and melanoma cialis professional ingredients and cialis with out a prescription tadalafil liquid fda approval date
https://tadalaccess.com/# tadalafil 5mg generic from us
buy generic cialis online: cialis 30 day free trial - tadacip tadalafil
cialis daily dosage: tadalafil generico farmacias del ahorro - cialis super active reviews
cialis with out a prescription buy cialis online overnight shipping us pharmacy prices for cialis
https://tadalaccess.com/# canadian pharmacy cialis brand
cialis online no prior prescription what is cialis used to treat or trusted online store to buy cialis
https://maps.google.co.kr/url?q=https://tadalaccess.com cialis goodrx
buy tadalafil online no prescription black cialis and cialis indien bezahlung mit paypal cheap cialis 20mg
cialis vs tadalafil: cialis copay card - cialis stopped working
tadalafil (megalis-macleods) reviews cialis strength or cialis dopoxetine
https://images.google.si/url?q=https://tadalaccess.com tadalafil tablets 20 mg reviews
cialis alcohol cialis com free sample and us pharmacy prices for cialis tadalafil tablets 40 mg
cialis paypal: cialis tadalafil 5mg once a day - best price cialis supper active
typical cialis prescription strength Tadal Access buy cialis usa
https://tadalaccess.com/# cialis stopped working
what is cialis pill: TadalAccess - cialis for sale in toront ontario
cialis online canada cialis for sale or tadalafil generic reviews
https://www.google.im/url?q=https://tadalaccess.com cialis 5mg daily how long before it works
is tadalafil from india safe cialis tadalafil discount and pastilla cialis cialis tadalafil 20mg tablets
buy cialis usa: TadalAccess - pictures of cialis
tadalafil 5mg once a day TadalAccess buy cialis tadalafil
https://tadalaccess.com/# cialis dopoxetine
cialis dopoxetine: buying generic cialis - cialis 5mg review
take cialis the correct way what is cialis pill or cialis 10mg price
http://www.reddelacosta.com.ar/propiedades/gprop.php?pagina=6&modo=V&pfondo=tadalaccess.com cialis 20 mg tablets and prices
cialis canadian pharmacy ezzz cialis super active real online store and max dosage of cialis cialis for enlarged prostate
online pharmacy cialis sunrise remedies tadalafil or tadalafil 20mg canada
https://www.google.com.ni/url?sa=t&url=https://tadalaccess.com cialis before and after
cialis 30 mg dose active ingredient in cialis and best time to take cialis 20mg best place to buy liquid tadalafil
cialis canadian purchase: sildenafil and tadalafil - cialis at canadian pharmacy
cialis 40 mg canadian pharmacy tadalafil 20mg bph treatment cialis
https://tadalaccess.com/# sildenafil vs tadalafil vs vardenafil
cialis 5mg price cvs: buying cialis internet - cialis male enhancement
cialis tadalafil viagara cialis levitra or cialis cheapest prices
https://images.google.es/url?sa=t&url=https://tadalaccess.com cialis where can i buy
buy cialis in toronto cialis black 800 mg pill house and cialis online delivery overnight cialis information
cialis 20 mg price walgreens: walgreen cialis price - when to take cialis for best results
https://tadalaccess.com/# cialis generic purchase
cialis free trial coupon cialis cheap tadalafil 20mg canada
cialis generic for sale: when does the cialis patent expire - cialis dosage side effects
bph treatment cialis cialis walmart or can you drink wine or liquor if you took in tadalafil
https://vatikan.pennergame.de/redirect/?site=https://tadalaccess.com canadian pharmacy tadalafil 20mg
cialis reviews photos cialis tadalafil online paypal and no prescription cialis buying cialis online
tadalafil 40 mg india generic tadalafil prices or tadalafil citrate bodybuilding
http://images.google.co.ug/url?q=https://tadalaccess.com tadalafil prescribing information
cialis buy australia online tadalafil citrate powder and tadalafil review side effects cialis
tadalafil daily use: Tadal Access - buy cialis online overnight delivery
https://tadalaccess.com/# how much does cialis cost per pill
cialis free trial canada: Tadal Access - cialis experience reddit
cialis tablet where to buy cialis online for cheap cialis for women
cialis stories buying cialis internet or tadalafil 20 mg directions
http://www.hannobunz.de/url?q=https://tadalaccess.com what happens if you take 2 cialis
cialis sample cialis manufacturer coupon and buy cialis pro cialis dosage for bph
https://tadalaccess.com/# how long does it take cialis to start working
where to get the best price on cialis: buy cialis generic online - cheap cialis pills uk
over the counter drug that works like cialis: Tadal Access - where to buy cialis over the counter
cialis milligrams cialis 20 mg vigra vs cialis
canada pharmacy cialis: what is cialis - cialis online delivery overnight
https://tadalaccess.com/# can tadalafil cure erectile dysfunction
cialis 5 mg price buy cialis by paypal or cialis 5 mg
http://ewin.biz/jsonp/?url=https://tadalaccess.com cialis 5mg price comparison
maximpeptide tadalafil review difference between sildenafil tadalafil and vardenafil and generic cialis cialis pill
when will teva's generic tadalafil be available in pharmacies cialis super active reviews or cialis 20 mg from united kingdom
http://nycbcares.com/leaving.php?U=http://tadalaccess.com/ best place to get cialis without pesricption
=]cialis drug class cialis discount coupons and cialis priligy online australia shelf life of liquid tadalafil
cialis generic canada: recreational cialis - cialis 10mg price
canada cialis generic Tadal Access buy cheap tadalafil online
cialis generic online: cialis pills pictures - maximpeptide tadalafil review
https://tadalaccess.com/# generic tadalafil canada
cialis price cvs cialis directions or when is the best time to take cialis
https://www.google.com.sa/url?q=http://tadalaccess.com purchase cialis online cheap
tadalafil oral jelly cialis samples and cialis prescription online where to buy cialis online
tadalafil best price 20 mg: Tadal Access - cialis pill canada
brand cialis Tadal Access price of cialis at walmart
where can i buy cialis on line: TadalAccess - cialis daily side effects
https://tadalaccess.com/# cialis milligrams
cialis dapoxetine overnight shipment: cialis indications - cialis 5 mg tablet
buy cialis online overnight shipping how long before sex should you take cialis or cialis canada
https://hardwareforums.com/proxy.php?link=https://tadalaccess.com cialis dosage for ed
tadalafil and voice problems pictures of cialis pills and cialis mit paypal bezahlen best place to buy generic cialis online
cialis 20mg price cialis australia online shopping or when should i take cialis
https://images.google.im/url?q=https://tadalaccess.com buy cialis free shipping
cialis 5mg coupon whats cialis and cialis in las vegas bph treatment cialis
cialis 20 mg price costco walgreens cialis prices cialis coupon code
blue sky peptide tadalafil review: Tadal Access - cialis alcohol
https://tadalaccess.com/# cialis 30 mg dose
cialis 10mg reviews: when will cialis be generic - can tadalafil cure erectile dysfunction
cialis for sale online cialis medicine or tadalafil soft tabs
http://www.google.com.ph/url?q=http://tadalaccess.com compounded tadalafil troche life span
purchase cialis online cheap san antonio cialis doctor and blue sky peptide tadalafil review find tadalafil
cheap tadalafil no prescription cialis cheapest prices buying cialis internet
tadalafil tablets 40 mg: TadalAccess - cialis purchase canada
https://tadalaccess.com/# what possible side effect should a patient taking tadalafil report to a physician quizlet
how to buy cialis: cialis or levitra - cialis generic purchase
order cialis online tadalafil online canadian pharmacy or mint pharmaceuticals tadalafil
http://cse.google.cat/url?sa=i&url=https://tadalaccess.com cialis package insert
cialis street price achats produit tadalafil pour femme en ligne and generic cialis tadalafil 20mg reviews cialis india
tadalafil without a doctor prescription cialis free sample or cialis free trial coupon
https://clients1.google.az/url?q=https://tadalaccess.com walgreens cialis prices
tadalafil generic reviews prescription for cialis and cialis experience forum is generic cialis available in canada
tadalafil daily use special sales on cialis cialis online without perscription
generic cialis tadalafil 20mg reviews: cialis priligy online australia - what happens when you mix cialis with grapefruit?
https://tadalaccess.com/# cialis 10mg price
best price on generic tadalafil what is the normal dose of cialis or buy cialis no prescription
http://www.kfiz.com/Redirect.aspx?destination=http://tadalaccess.com/ where to buy cialis cheap
п»їwhat can i take to enhance cialis how to get cialis without doctor and where to buy cialis cialis for daily use
cialis and nitrates: tadalafil 5 mg tablet - buy tadalafil online paypal
para que sirve las tabletas cialis tadalafil de 5mg: Tadal Access - cialis no perscription overnight delivery
buying generic cialis online safe Tadal Access e-cialis hellocig e-liquid
https://tadalaccess.com/# cialis online without pres
cialis 5mg how long does it take to work: TadalAccess - online cialis
buy cialis online free shipping: cialis free - tadalafil softsules tuf 20
buy cialis online reddit cialis daily side effects or cialis 20 mg duration
http://clients1.google.com.ni/url?q=https://tadalaccess.com:: tadalafil citrate research chemical
buy cialis with dapoxetine in canada combitic global caplet pvt ltd tadalafil and cialis online no prescription australia cialis dapoxetine overnight shipment
cialis prostate cialis daily vs regular cialis canadian pharmacy online cialis
https://tadalaccess.com/# canadian pharmacy ezzz cialis
cialis dose cialis pills pictures or buying cialis in mexico
https://www.google.ms/url?sa=t&url=https://tadalaccess.com is there a generic equivalent for cialis
cialis at canadian pharmacy canadian pharmacy ezzz cialis and what is cialis good for cialis free trial canada
cialis strength: Tadal Access - tadalafil 5mg once a day
poppers and cialis: TadalAccess - cialis on sale
https://tadalaccess.com/# buy cialis online without prescription
us pharmacy prices for cialis cialis free or cialis is for daily use
http://www.go.pornfetishforum.com/?http://tadalaccess.com/ achats produit tadalafil pour femme en ligne
what is tadalafil made from tadalafil citrate powder and how to get cialis prescription online cialis strength
cialis generic cvs letairis and tadalafil cialis overnight shipping
what is the cost of cialis: TadalAccess - how long does cialis take to work
https://tadalaccess.com/# cialis tadalafil 20mg price
cialis online pharmacy australia: Tadal Access - mint pharmaceuticals tadalafil reviews
tadalafil 40 mg with dapoxetine 60 mg most recommended online pharmacies cialis or cialis online overnight shipping
https://www.google.co.th/url?q=https://tadalaccess.com cialis generic purchase
buy cialis generic online buying cialis online and where to buy tadalafil in singapore cialis from india online pharmacy
overnight cialis delivery generic cialis tadalafil 20mg india cialis side effects
cialis copay card cialis daily or cialis stopped working
https://maps.google.pt/url?q=https://tadalaccess.com walgreen cialis price
benefits of tadalafil over sidenafil viagara cialis levitra and buy cialis in las vegas best price on generic cialis
is there a generic cialis available: cialis side effects with alcohol - oryginal cialis
https://tadalaccess.com/# cialis black 800 mg pill house
cialis las vegas: side effects of cialis - cialis 20mg price
cialis experience TadalAccess where to get generic cialis without prescription
buying cialis internet: cialis patent - cialis and cocaine
https://tadalaccess.com/# cialis buy australia online
buying generic cialis online safe: nebenwirkungen tadalafil - cialis effect on blood pressure
cialis insurance coverage generic cialis 5mg generic tadalafil 40 mg
cialis generic timeline cialis online pharmacy australia or order cialis from canada
https://www.google.co.th/url?q=https://tadalaccess.com cialis tadalafil 20mg price
cheap cialis canada cialis sample request form and canadian pharmacy cialis brand maxim peptide tadalafil citrate
cialis tadalafil 20 mg cialis tadalafil 20mg kaufen or canada cialis for sale
http://www.red-ring.com/rssnewsitem.php?urltodisplay=http://tadalaccess.com cialis patent
which is better cialis or levitra what does a cialis pill look like and mambo 36 tadalafil 20 mg reviews cialis canada free sample
cialis 20 mg price costco: Tadal Access - cialis price
https://tadalaccess.com/# what happens if a woman takes cialis
cialis next day delivery: Tadal Access - shelf life of liquid tadalafil
can you drink alcohol with cialis Tadal Access tadalafil citrate liquid
cialis milligrams canada pharmacy cialis or cialis online with no prescription
https://www.google.cd/url?sa=t&url=https://tadalaccess.com cialis prices in mexico
cialis for bph insurance coverage cialis instructions and cialis overdose tadalafil citrate research chemical
where to buy cialis over the counter: buy cialis no prescription overnight - cialis 30 mg dose
https://tadalaccess.com/# cialis pills pictures
tadalafil cheapest online: cialis tubs - no prescription tadalafil
order generic cialis online Tadal Access buy cialis pro
buy cialis online in austalia: Tadal Access - cialis doesnt work for me
too much cialis cheap generic cialis canada or mint pharmaceuticals tadalafil reviews
http://kinhtexaydung.net/redirect/?url=https://tadalaccess.com cialis where to buy in las vegas nv
cialis active ingredient cialis buy and cialis online canada tadalafil generic reviews
https://tadalaccess.com/# canadian no prescription pharmacy cialis
cialis doesnt work for me maximum dose of tadalafil or pastilla cialis
https://www.google.com.mx/url?q=https://tadalaccess.com cialis one a day
cialis package insert cialis manufacturer coupon free trial and canadian pharmacy cialis brand mint pharmaceuticals tadalafil reviews
cialis online reviews: TadalAccess - can cialis cause high blood pressure
cheap tadalafil 10mg: generic cialis 20 mg from india - sildenafil and tadalafil
cialis headache cialis experience forum cialis prices
cialis by mail mambo 36 tadalafil 20 mg reviews or what are the side effect of cialis
http://naiyoujc.ff66.net/productshow.asp?id=30&mnid=51913&url=http://tadalaccess.com п»їwhat can i take to enhance cialis
what is the active ingredient in cialis cialis and cocaine and how long before sex should i take cialis cialis or levitra
https://tadalaccess.com/# taking cialis
reddit cialis: tadalafil softsules tuf 20 - cialis what is it
is tadalafil from india safe: no prescription female cialis - walgreen cialis price
pastilla cialis TadalAccess cialis cheapest prices
https://tadalaccess.com/# tadalafil vs sildenafil
where to buy cialis cheap: TadalAccess - tadalafil dose for erectile dysfunction
cialis walmart: TadalAccess - cialis 10mg ireland
https://tadalaccess.com/# difference between sildenafil tadalafil and vardenafil
maximpeptide tadalafil review canadian pharmacy online cialis canadian cialis
buying cialis in canada: Tadal Access - tadalafil 20mg (generic equivalent to cialis)
price comparison tadalafil: price comparison tadalafil - when will cialis be generic
https://tadalaccess.com/# peptide tadalafil reddit
cialis headache TadalAccess tadalafil no prescription forum
tadalafil liquid fda approval date: TadalAccess - buy tadalafil no prescription
cialis once a day: Tadal Access - cialis online overnight shipping
https://tadalaccess.com/# cialis sample
stockists of cialis TadalAccess cialis website
cialis buy online canada: cialis for ed - what is the use of tadalafil tablets
where to buy clomid without prescription where buy generic clomid without a prescription or where can i buy cheap clomid price
http://djebel-club.ru/r.php?r=clomhealth.com get cheap clomid no prescription
where to get clomid now get generic clomid without rx and how can i get clomid without rx can i buy clomid for sale
prednisone canada pharmacy purchase prednisone from india or prednisone 20 mg generic
https://www.google.co.il/url?q=https://prednihealth.shop prednisone 1 tablet
how to buy prednisone online prednisone 2.5 mg price and prednisone 20mg for sale prednisone sale
Amo Health Care: amoxicillin 500mg capsules uk - amoxicillin pharmacy price
http://clomhealth.com/# where buy cheap clomid without insurance
where buy clomid pills: Clom Health - where can i get generic clomid without prescription
PredniHealth prednisone 5mg price PredniHealth
amoxicillin online without prescription amoxicillin 500mg tablets price in india or generic amoxicillin online
https://www.google.so/url?q=https://amohealthcare.store amoxicillin 500
where can i get amoxicillin where can i buy amoxicillin over the counter and amoxicillin 500 mg cost where can you get amoxicillin
buy amoxicillin without prescription: Amo Health Care - amoxicillin 500mg tablets price in india
https://amohealthcare.store/# Amo Health Care
Amo Health Care: Amo Health Care - Amo Health Care
prednisone in canada prednisone in canada cost of prednisone 40 mg
where can i buy clomid without insurance buy clomid without rx or cost of clomid prices
https://roland.pri.ee/wiki/?a=link&url=https://clomhealth.com order clomid no prescription
can i get cheap clomid tablets where can i get generic clomid no prescription and where buy clomid without a prescription how to get cheap clomid without insurance
where to buy clomid: can i order cheap clomid - how can i get clomid prices
https://amohealthcare.store/# Amo Health Care
get generic clomid pills: cheap clomid without dr prescription - order generic clomid without rx
medicine prednisone 5mg canada pharmacy prednisone or prednisone brand name
https://www.google.sr/url?q=https://prednihealth.shop generic prednisone cost
no prescription online prednisone prednisone in uk and how to get prednisone without a prescription prednisone uk buy
prednisone price prednisone no rx prednisone without prescription.net
can you buy cheap clomid pill: Clom Health - where can i buy clomid without a prescription
https://clomhealth.shop/# can i get cheap clomid no prescription
best pharmacy prednisone: PredniHealth - PredniHealth
amoxicillin medicine generic amoxicillin online or amoxicillin 500mg capsule
https://toolbarqueries.google.com.bo/url?q=https://amohealthcare.store amoxicillin without rx
buy amoxicillin without prescription amoxicillin 500mg cost and amoxicillin 875 125 mg tab amoxicillin online pharmacy
can i order clomid pill: Clom Health - can you get cheap clomid without a prescription
buying prednisone on line prednisone 50 mg buy buy prednisone online uk
prednisone steroids prednisone buy or prednisone buy online nz
https://www.google.com.mx/url?q=https://prednihealth.com 400 mg prednisone
prednisone 30 mg tablet buy prednisone 40 mg and 5 mg prednisone daily prednisone drug costs
rexall pharmacy amoxicillin 500mg: amoxicillin 500mg buy online uk - Amo Health Care
prednisone 7.5 mg: prednisone online paypal - prednisone 200 mg tablets
prednisone 2.5 tablet: PredniHealth - PredniHealth
can i buy amoxicillin over the counter in australia can you buy amoxicillin uk Amo Health Care
buy generic clomid: can i order generic clomid without a prescription - where can i get generic clomid pills
can i purchase clomid price: where buy generic clomid tablets - cost of clomid
https://prednihealth.shop/# PredniHealth
can you buy generic clomid no prescription: buying generic clomid without insurance - where to buy generic clomid no prescription
where can i get generic clomid now Clom Health how can i get generic clomid without insurance
clomid prices: can i purchase clomid - get cheap clomid without insurance
amoxicillin 50 mg tablets: Amo Health Care - Amo Health Care
https://amohealthcare.store/# Amo Health Care
Amo Health Care: Amo Health Care - where can i buy amoxocillin
Amo Health Care: where can i buy amoxicillin without prec - where can i get amoxicillin 500 mg
Amo Health Care: Amo Health Care - Amo Health Care
Amo Health Care amoxicillin 500mg pill how to get amoxicillin
https://prednihealth.shop/# prednisone over the counter south africa
safe modafinil purchase: purchase Modafinil without prescription - buy modafinil online
modafinil 2025 legal Modafinil purchase or modafinil pharmacy
https://cse.google.vg/url?q=https://modafinilmd.store modafinil pharmacy
purchase Modafinil without prescription doctor-reviewed advice and legal Modafinil purchase purchase Modafinil without prescription
verified Modafinil vendors: doctor-reviewed advice - modafinil pharmacy
FDA approved generic Cialis: Cialis without prescription - buy generic Cialis online
FDA approved generic Cialis affordable ED medication or best price Cialis tablets
https://gr.k24.net/feeds/frontwidget.aspx?fc=000000&f=1&p=3146&url=https://zipgenericmd.com Cialis without prescription
affordable ED medication reliable online pharmacy Cialis and secure checkout ED drugs secure checkout ED drugs
legit Viagra online: same-day Viagra shipping - best price for Viagra
best price Cialis tablets: affordable ED medication - discreet shipping ED pills
secure checkout Viagra trusted Viagra suppliers or no doctor visit required
https://www.google.ad/url?sa=t&url=https://maxviagramd.shop order Viagra discreetly
secure checkout Viagra trusted Viagra suppliers and generic sildenafil 100mg same-day Viagra shipping
same-day Viagra shipping: trusted Viagra suppliers - Viagra without prescription
https://modafinilmd.store/# modafinil pharmacy
secure checkout ED drugs cheap Cialis online or FDA approved generic Cialis
https://toolbarqueries.google.co.bw/url?q=https://zipgenericmd.com secure checkout ED drugs
FDA approved generic Cialis discreet shipping ED pills and Cialis without prescription affordable ED medication
modafinil 2025: doctor-reviewed advice - modafinil pharmacy
modafinil pharmacy: legal Modafinil purchase - Modafinil for sale
buy modafinil online buy modafinil online or verified Modafinil vendors
http://tyadnetwork.com/ads_top.php?url=https://modafinilmd.store/ verified Modafinil vendors
modafinil legality doctor-reviewed advice and modafinil pharmacy doctor-reviewed advice
online Cialis pharmacy: online Cialis pharmacy - reliable online pharmacy Cialis
http://maxviagramd.com/# best price for Viagra
cheap Cialis online secure checkout ED drugs or order Cialis online no prescription
https://maps.google.iq/url?q=https://zipgenericmd.com Cialis without prescription
reliable online pharmacy Cialis secure checkout ED drugs and Cialis without prescription secure checkout ED drugs
verified Modafinil vendors: Modafinil for sale - modafinil pharmacy
modafinil 2025: doctor-reviewed advice - safe modafinil purchase
fast Viagra delivery: best price for Viagra - no doctor visit required
Modafinil for sale modafinil legality modafinil pharmacy
buy generic Viagra online safe online pharmacy or safe online pharmacy
http://jm.57883.net/alexa/jm/index.asp?domain=maxviagramd.shop safe online pharmacy
no doctor visit required no doctor visit required and same-day Viagra shipping discreet shipping
http://modafinilmd.store/# modafinil 2025
order Cialis online no prescription online Cialis pharmacy or FDA approved generic Cialis
http://www.newhopebible.net/System/Login.asp?id=49429&Referer=http://zipgenericmd.com Cialis without prescription
best price Cialis tablets buy generic Cialis online and cheap Cialis online cheap Cialis online
legal Modafinil purchase: modafinil legality - purchase Modafinil without prescription
reliable online pharmacy Cialis: order Cialis online no prescription - reliable online pharmacy Cialis
legal Modafinil purchase verified Modafinil vendors or modafinil pharmacy
https://www.google.mv/url?q=https://modafinilmd.store doctor-reviewed advice
buy modafinil online safe modafinil purchase and modafinil pharmacy legal Modafinil purchase
https://maxviagramd.com/# no doctor visit required
buy modafinil online: buy modafinil online - safe modafinil purchase
same-day Viagra shipping: buy generic Viagra online - no doctor visit required
discreet shipping: generic sildenafil 100mg - no doctor visit required
buy generic Viagra online safe online pharmacy cheap Viagra online
http://zipgenericmd.com/# reliable online pharmacy Cialis
cheap Viagra online best price for Viagra or generic sildenafil 100mg
https://www.google.so/url?q=https://maxviagramd.shop Viagra without prescription
safe online pharmacy Viagra without prescription and legit Viagra online discreet shipping
order Cialis online no prescription cheap Cialis online or generic tadalafil
https://www.google.bs/url?q=https://zipgenericmd.com affordable ED medication
FDA approved generic Cialis FDA approved generic Cialis and secure checkout ED drugs order Cialis online no prescription
Cialis without prescription: secure checkout ED drugs - buy generic Cialis online
discreet shipping ED pills: online Cialis pharmacy - generic tadalafil
order Cialis online no prescription: buy generic Cialis online - discreet shipping ED pills
safe modafinil purchase modafinil legality or modafinil 2025
https://clients1.google.sc/url?q=https://modafinilmd.store buy modafinil online
buy modafinil online safe modafinil purchase and safe modafinil purchase legal Modafinil purchase
modafinil legality: doctor-reviewed advice - purchase Modafinil without prescription
Viagra without prescription trusted Viagra suppliers discreet shipping
http://modafinilmd.store/# verified Modafinil vendors
buy modafinil online: Modafinil for sale - modafinil pharmacy
purchase Modafinil without prescription: purchase Modafinil without prescription - modafinil 2025
reliable online pharmacy Cialis reliable online pharmacy Cialis or order Cialis online no prescription
https://www.google.com.ai/url?q=https://zipgenericmd.com affordable ED medication
buy generic Cialis online affordable ED medication and reliable online pharmacy Cialis affordable ED medication
generic tadalafil best price Cialis tablets reliable online pharmacy Cialis
secure checkout Viagra discreet shipping or Viagra without prescription
https://www.google.lv/url?sa=t&url=https://maxviagramd.shop trusted Viagra suppliers
buy generic Viagra online same-day Viagra shipping and trusted Viagra suppliers legit Viagra online
best price Cialis tablets: discreet shipping ED pills - Cialis without prescription
legal Modafinil purchase: purchase Modafinil without prescription - modafinil pharmacy
online Cialis pharmacy: discreet shipping ED pills - Cialis without prescription
http://modafinilmd.store/# modafinil legality
verified Modafinil vendors doctor-reviewed advice or doctor-reviewed advice
https://maps.google.pl/url?q=https://modafinilmd.store safe modafinil purchase
buy modafinil online verified Modafinil vendors and modafinil pharmacy Modafinil for sale
generic sildenafil 100mg best price for Viagra buy generic Viagra online
Cialis without prescription: online Cialis pharmacy - buy generic Cialis online
legit Viagra online: fast Viagra delivery - buy generic Viagra online
https://maxviagramd.com/# legit Viagra online
order Cialis online no prescription: best price Cialis tablets - discreet shipping ED pills
fast Viagra delivery: same-day Viagra shipping - safe online pharmacy
safe modafinil purchase safe modafinil purchase Modafinil for sale
Modafinil for sale: buy modafinil online - doctor-reviewed advice
https://modafinilmd.store/# purchase Modafinil without prescription
best price Cialis tablets: best price Cialis tablets - discreet shipping ED pills
order Cialis online no prescription: Cialis without prescription - buy generic Cialis online
buy generic Cialis online buy generic Cialis online best price Cialis tablets
Modafinil for sale: buy modafinil online - verified Modafinil vendors
secure checkout Viagra: fast Viagra delivery - no doctor visit required
modafinil 2025: buy modafinil online - modafinil 2025
https://maxviagramd.com/# best price for Viagra
legal Modafinil purchase modafinil legality Modafinil for sale
Viagra without prescription: discreet shipping - order Viagra discreetly
https://pinupaz.top/# pin up azerbaycan
вавада официальный сайт: vavada - vavada вход
pin up casino: pinup az - pin up
вавада официальный сайт: вавада зеркало - вавада казино
pin up casino pinup az pin up
https://pinupaz.top/# pin up az
vavada casino: vavada - вавада
вавада: вавада казино - вавада официальный сайт
пин ап казино официальный сайт пин ап казино официальный сайт пин ап казино
http://pinuprus.pro/# пин ап казино
vavada: вавада официальный сайт - вавада
вавада казино vavada casino or вавада
http://www.johnsongt.com/link.php?name=deezee&addr=vavadavhod.tech вавада казино
вавада vavada casino and vavada вавада
https://pinuprus.pro/# пин ап казино официальный сайт
pin up azerbaycan: pin up - pinup az
пин ап вход пин ап зеркало or пин ап зеркало
http://maps.google.fi/url?q=https://pinuprus.pro пин ап казино официальный сайт
[url=https://www.google.gg/url?q=https://pinuprus.pro]пин ап зеркало[/url] пин ап вход and [url=http://www.xgmoli.com/bbs/home.php?mod=space&uid=7948]пин ап казино[/url] пин ап зеркало
pin up: pinup az - pinup az
вавада официальный сайт: вавада казино - вавада
пин ап зеркало пинап казино or пинап казино
https://www.google.mn/url?sa=t&url=https://pinuprus.pro пин ап казино официальный сайт
пин ап казино пин ап казино официальный сайт and пин ап вход пин ап казино
pin up вход пин ап вход or пин ап зеркало
http://www.barwitzki.net/mecstats/index.php?page=reffer_detail&dom=pinuprus.pro пин ап зеркало
пин ап казино pin up вход and пин ап зеркало pin up вход
vavada casino: вавада казино - вавада зеркало
pinup az pin up pin up casino
вавада официальный сайт вавада vavada casino
pin-up casino giris: pin up - pin up az
http://pinupaz.top/# pin up az
пин ап зеркало пин ап казино or пин ап вход
https://www.google.so/url?q=https://pinuprus.pro пин ап казино официальный сайт
пин ап казино официальный сайт пинап казино and пин ап вход пинап казино
пин ап вход пин ап вход пин ап казино
pin up casino: pin up - pin-up
вавада: вавада официальный сайт - vavada вход
пинап казино пин ап казино or пинап казино
https://cse.google.com.ph/url?sa=t&url=https://pinuprus.pro пин ап казино официальный сайт
пинап казино пин ап казино and пинап казино пин ап вход
pin up casino pin up azerbaycan pin up azerbaycan
pin up azerbaycan: pin up casino - pin up az
пин ап казино: пин ап зеркало - пин ап казино официальный сайт
pin-up: pin up az - pin up az
https://pinuprus.pro/# пинап казино
вавада казино: vavada casino - вавада зеркало
вавада официальный сайт вавада официальный сайт or vavada
http://fortrucker-env.com/leaving.aspx?ext=http://vavadavhod.tech vavada casino
vavada вход vavada вход and vavada вавада официальный сайт
вавада официальный сайт vavada casino vavada casino
https://pinuprus.pro/# пинап казино
пин ап вход: пин ап казино - пин ап вход
pin up azerbaycan: pin up azerbaycan - pin up
https://pinuprus.pro/# пин ап казино
vavada вход: vavada вход - вавада
http://vavadavhod.tech/# вавада зеркало
pin-up casino giris: pin up - pin-up casino giris
pin up вход: пин ап казино - пин ап вход
vavada casino vavada вход or вавада казино
https://www.google.com.bz/url?q=https://vavadavhod.tech вавада
вавада вавада официальный сайт and вавада официальный сайт вавада казино
пинап казино пин ап казино официальный сайт or пин ап зеркало
http://maps.google.cf/url?q=http://pinuprus.pro пин ап казино
pin up вход пин ап вход and пинап казино pin up вход
пин ап зеркало: пин ап казино официальный сайт - пин ап казино официальный сайт
vavada casino [url=https://vavadavhod.tech/#]вавада[/url] vavada
pin-up pin-up casino giris or pin-up casino giris
http://www.arakhne.org/redirect.php?url=https://pinupaz.top pin-up casino giris
[url=https://www.google.me/url?q=https://pinupaz.top]pin up azerbaycan[/url] pin-up and [url=http://lzdsxxb.com/home.php?mod=space&uid=4392613]pinup az[/url] pin up
вавада: vavada casino - вавада казино
пинап казино пин ап казино официальный сайт пин ап зеркало
вавада официальный сайт vavada or vavada вход
https://www.htcdev.com/?URL=vavadavhod.tech вавада зеркало
вавада вавада казино and vavada casino vavada
pin up azerbaycan pin up az or pinup az
https://maps.google.si/url?sa=t&url=https://pinupaz.top pin up
pinup az pin up azerbaycan and pin up az pin up az
пинап казино pin up вход pin up вход
пин ап казино официальный сайт: пин ап зеркало - pin up вход
пинап казино пин ап казино официальный сайт or пин ап зеркало
http://dvd24online.de/url?q=https://pinuprus.pro пин ап казино
пинап казино пинап казино and пин ап зеркало пинап казино
pin up azerbaycan: pin up - pin up azerbaycan
http://pinupaz.top/# pin-up casino giris
pin up вход пин ап зеркало pin up вход
pin up az: pinup az - pin up azerbaycan
пин ап казино официальный сайт пин ап вход пин ап казино
пин ап вход пин ап зеркало or пин ап зеркало
http://www.78901.net/alexa/index.asp?url=pinuprus.pro pin up вход
пин ап казино официальный сайт пин ап вход and пинап казино пин ап казино
pin up casino pin-up casino giris or pin-up casino giris
https://maps.google.gr/url?sa=t&url=https://pinupaz.top pin up casino
pin up azerbaycan pinup az and pin up pin-up casino giris
пин ап казино pin up вход or пин ап казино
https://maps.google.ad/url?q=https://pinuprus.pro пин ап зеркало
пин ап зеркало пин ап зеркало and пин ап вход пин ап казино
vavada casino: вавада - вавада официальный сайт
https://vavadavhod.tech/# vavada вход
pin up pin up pin-up casino giris
пин ап казино официальный сайт: пин ап казино - пин ап зеркало
пин ап казино официальный сайт пин ап вход or пин ап казино
http://www.cherrybb.jp/test/link.cgi/pinuprus.pro пинап казино
pin up вход пин ап казино and пинап казино пинап казино
pin up az pin up casino or pin up
https://www.google.com.mx/url?sa=t&url=https://pinupaz.top pin up az
pin up az pin-up casino giris and pin up casino pin up az
пин ап казино официальный сайт пинап казино or пин ап казино официальный сайт
http://www.slotgemeinde.de/go.php?url=http://pinuprus.pro pin up вход
пин ап казино пин ап казино and пин ап вход пин ап вход
pin up вход: пинап казино - пин ап вход
пин ап вход пин ап казино официальный сайт or пин ап зеркало
https://soccer.sincsports.com/ttlogin.aspx?tid=german&dfix=y&domain=pinuprus.pro пин ап казино
пин ап зеркало пин ап зеркало and пинап казино пин ап казино официальный сайт
вавада: вавада - vavada
пинап казино: пинап казино - пин ап казино официальный сайт
пинап казино pin up вход pin up вход
pin up вход пин ап казино or пин ап казино
https://images.google.co.ve/url?q=https://pinuprus.pro пин ап казино официальный сайт
pin up вход pin up вход and пин ап вход пин ап зеркало
https://vavadavhod.tech/# vavada вход
пин ап казино: пин ап зеркало - пин ап казино официальный сайт
пин ап казино: пин ап казино - pin up вход
http://pinuprus.pro/# пинап казино
pin up azerbaycan: pin up azerbaycan - pin up az
pin up azerbaycan: pin up azerbaycan - pin up
pin up az: pin-up casino giris - pin-up
пин ап казино пин ап вход or пинап казино
http://www.joi3.com/go.php?url=http://pinuprus.pro/ пин ап вход
пин ап казино официальный сайт пинап казино and пинап казино пин ап казино
https://vavadavhod.tech/# vavada casino
pinup az: pin-up casino giris - pin up az
pin up вход: пин ап казино - пин ап казино официальный сайт
вавада вавада зеркало or вавада казино
http://w-ecolife.com/feed2js/feed2js.php?src=https://vavadavhod.tech vavada
вавада официальный сайт вавада зеркало and вавада зеркало вавада зеркало
https://pinuprus.pro/# пин ап вход
pinup az: pinup az - pin up azerbaycan
pin up вход пин ап зеркало or пин ап казино официальный сайт
http://4chan.nbbs.biz/kusyon_b.php?http://pinuprus.pro/ пин ап вход
пин ап казино официальный сайт пин ап казино официальный сайт and pin up вход пинап казино
vavada: вавада - вавада казино
пин ап казино пинап казино пин ап зеркало
http://pinupaz.top/# pin-up casino giris
вавада казино: vavada casino - вавада казино
пин ап казино: pin up вход - пин ап казино
http://vavadavhod.tech/# вавада
пин ап казино пинап казино пин ап зеркало
вавада: vavada casino - вавада официальный сайт
pin up az: pin up azerbaycan - pin up casino
pin-up casino giris: pin up azerbaycan - pin up casino
вавада vavada вход vavada casino
pin up casino: pinup az - pin-up casino giris
http://pinuprus.pro/# пин ап казино официальный сайт
пин ап зеркало: пин ап казино официальный сайт - пин ап казино
пин ап вход пин ап казино pin up вход
пин ап казино: pin up вход - пин ап вход
http://pinuprus.pro/# пинап казино
вавада зеркало: вавада зеркало - вавада зеркало
canadian pharmacy online: Buy medicine from Canada - best mail order pharmacy canada
Rx Express Mexico mexico pharmacies prescription drugs mexico drug stores pharmacies
india pharmacy mail order india online pharmacy or cheapest online pharmacy india
http://www.e-decor.com.ua/go/?fid=53&url=https://medicinefromindia.com buy medicines online in india
indian pharmacy online india pharmacy mail order and reputable indian online pharmacy best online pharmacy india
http://expressrxcanada.com/# best canadian online pharmacy
purple pharmacy mexico price list: RxExpressMexico - Rx Express Mexico
best canadian pharmacy online reddit canadian pharmacy or onlinepharmaciescanada com
https://cse.google.gp/url?q=https://expressrxcanada.com canadian pharmacy
canadian drugs online canadian valley pharmacy and pharmacy rx world canada cross border pharmacy canada
buying from online mexican pharmacy: RxExpressMexico - mexican rx online
canadian pharmacy cheap Buy medicine from Canada canada online pharmacy
http://rxexpressmexico.com/# mexico pharmacies prescription drugs
canada drugstore pharmacy rx: Express Rx Canada - canadian pharmacy 24h com
best india pharmacy indian pharmacy online or top 10 pharmacies in india
https://www.google.co.vi/url?q=https://medicinefromindia.com indian pharmacies safe
mail order pharmacy india Online medicine home delivery and india online pharmacy best india pharmacy
canadian pharmacies that deliver to the us: Express Rx Canada - rate canadian pharmacies
medication from mexico pharmacy reputable mexican pharmacies online or mexican drugstore online
https://maps.google.co.ao/url?sa=t&url=https://rxexpressmexico.com mexican mail order pharmacies
pharmacies in mexico that ship to usa medicine in mexico pharmacies and mexican online pharmacies prescription drugs best online pharmacies in mexico
Medicine From India: indian pharmacy online shopping - MedicineFromIndia
mexican rx online mexico drug stores pharmacies mexico pharmacies prescription drugs
https://expressrxcanada.com/# pharmacies in canada that ship to the us
Rx Express Mexico: mexico drug stores pharmacies - Rx Express Mexico
top 10 online pharmacy in india best online pharmacy india or top online pharmacy india
http://rusnor.org/bitrix/redirect.php?event1=&event2=&event3=&goto=https://medicinefromindia.com/ Online medicine home delivery
п»їlegitimate online pharmacies india best india pharmacy and pharmacy website india п»їlegitimate online pharmacies india
canada drugs reviews: Canadian pharmacy shipping to USA - canadian pharmacy mall
canada pharmacy: Buy medicine from Canada - canadian pharmacies comparison
best online canadian pharmacy cross border pharmacy canada or canadian pharmacy no scripts
http://www.ohashi-co.com/w3a/redirect.php?redirect=http://expressrxcanada.com trusted canadian pharmacy
canadian drug pharmacy my canadian pharmacy rx and best canadian online pharmacy my canadian pharmacy
https://rxexpressmexico.shop/# reputable mexican pharmacies online
indian pharmacy online shopping: Medicine From India - Medicine From India
reputable indian online pharmacy buy medicines online in india or india pharmacy mail order
http://www.linkestan.com/frame-click.asp?url=https://medicinefromindia.com indian pharmacies safe
Medicine From India indian pharmacy online MedicineFromIndia
Medicine From India: medicine courier from India to USA - indian pharmacy online shopping
canadian king pharmacy: Canadian pharmacy shipping to USA - online canadian pharmacy review
mexico pharmacies prescription drugs medicine in mexico pharmacies or mexican border pharmacies shipping to usa
http://nicosoap.com/shop/display_cart?return_url=http://rxexpressmexico.com best online pharmacies in mexico
medication from mexico pharmacy п»їbest mexican online pharmacies and mexico drug stores pharmacies best online pharmacies in mexico
https://medicinefromindia.com/# indian pharmacy online
canadian pharmacy no scripts: Express Rx Canada - pharmacy canadian
mexico pharmacies prescription drugs Rx Express Mexico mexico pharmacies prescription drugs
legit canadian online pharmacy: Canadian pharmacy shipping to USA - legitimate canadian mail order pharmacy
mail order pharmacy india reputable indian online pharmacy or buy prescription drugs from india
https://forum.keenswh.com/proxy.php?link=http://medicinefromindia.com indianpharmacy com
online shopping pharmacy india top 10 pharmacies in india and world pharmacy india indian pharmacy paypal
https://rxexpressmexico.shop/# Rx Express Mexico
precription drugs from canada: ExpressRxCanada - canadian pharmacies online
Medicine From India: Medicine From India - indian pharmacy online shopping
best india pharmacy best india pharmacy or mail order pharmacy india
https://www.crucible-technologies.co.uk/registrationcomplete.aspx?returnurl=https://medicinefromindia.com online pharmacy india
buy medicines online in india mail order pharmacy india and Online medicine order top 10 pharmacies in india
mexico pharmacy order online: mexico pharmacies prescription drugs - mexico pharmacies prescription drugs
indian pharmacy indian pharmacy medicine courier from India to USA
https://rxexpressmexico.com/# mexico drug stores pharmacies
Online medicine order: Medicine From India - medicine courier from India to USA
mexican rx online: Rx Express Mexico - Rx Express Mexico
buying drugs from canada: Buy medicine from Canada - canadian pharmacy price checker
canadian drug prices Express Rx Canada legit canadian pharmacy online
http://expressrxcanada.com/# canadian pharmacy
canadian pharmacy checker: Express Rx Canada - legitimate canadian pharmacy
canadian pharmacy price checker: ExpressRxCanada - my canadian pharmacy rx
mexico pharmacy order online: mexico pharmacy order online - RxExpressMexico
Medicine From India MedicineFromIndia MedicineFromIndia
п»їpharmacie en ligne france: pharmacie en ligne - pharmacie en ligne pas cher pharmafst.com
Tadalafil 20 mg prix en pharmacie Acheter Viagra Cialis sans ordonnance or Acheter Cialis
https://images.google.cd/url?q=https://tadalmed.com Tadalafil 20 mg prix en pharmacie
Cialis sans ordonnance 24h Cialis en ligne and Cialis en ligne Tadalafil sans ordonnance en ligne
pharmacie en ligne france pas cher: pharmacie en ligne - pharmacie en ligne sans ordonnance pharmafst.com
https://pharmafst.shop/# pharmacie en ligne pas cher
Tadalafil sans ordonnance en ligne: Acheter Viagra Cialis sans ordonnance - Acheter Cialis 20 mg pas cher tadalmed.shop
Tadalafil sans ordonnance en ligne Acheter Cialis 20 mg pas cher Cialis sans ordonnance pas cher tadalmed.com
Acheter Kamagra site fiable: Kamagra Commander maintenant - kamagra livraison 24h
kamagra 100mg prix: Kamagra Oral Jelly pas cher - Achetez vos kamagra medicaments
http://tadalmed.com/# Tadalafil 20 mg prix en pharmacie
Cialis sans ordonnance pas cher: Cialis sans ordonnance 24h - Acheter Cialis tadalmed.shop
п»їpharmacie en ligne france trouver un mГ©dicament en pharmacie or pharmacie en ligne france pas cher
https://maps.google.to/url?q=https://pharmafst.com pharmacie en ligne pas cher
pharmacie en ligne france fiable vente de mГ©dicament en ligne and trouver un mГ©dicament en pharmacie pharmacie en ligne avec ordonnance
https://kamagraprix.shop/# kamagra livraison 24h
Tadalafil 20 mg prix sans ordonnance: Tadalafil sans ordonnance en ligne - Acheter Cialis 20 mg pas cher tadalmed.shop
Cialis sans ordonnance 24h: Acheter Cialis 20 mg pas cher - Tadalafil achat en ligne tadalmed.shop
п»їpharmacie en ligne france pharmacie en ligne france livraison belgique or pharmacie en ligne france livraison internationale
https://ticketonline.kiwikinos.ch/Kiwi/Show/926757?BackLink=https://pharmafst.com п»їpharmacie en ligne france
pharmacie en ligne Pharmacie sans ordonnance and pharmacie en ligne pas cher pharmacie en ligne sans ordonnance
https://tadalmed.shop/# Tadalafil 20 mg prix sans ordonnance
cialis sans ordonnance cialis generique or Acheter Viagra Cialis sans ordonnance
https://maps.google.ba/url?q=https://tadalmed.com cialis generique
Acheter Viagra Cialis sans ordonnance Tadalafil sans ordonnance en ligne and Cialis generique prix Pharmacie en ligne Cialis sans ordonnance
acheter kamagra site fiable: kamagra en ligne - kamagra en ligne
https://pharmafst.shop/# pharmacie en ligne france fiable
Kamagra Oral Jelly pas cher: kamagra gel - Achetez vos kamagra medicaments
https://tadalmed.shop/# Acheter Viagra Cialis sans ordonnance
Pharmacie Internationale en ligne Pharmacie en ligne livraison Europe or Pharmacie Internationale en ligne
http://cse.google.com.ai/url?sa=t&url=http://pharmafst.com pharmacie en ligne france livraison internationale
pharmacie en ligne pas cher pharmacie en ligne france livraison internationale and pharmacies en ligne certifiГ©es acheter mГ©dicament en ligne sans ordonnance
Pharmacie en ligne livraison Europe: Medicaments en ligne livres en 24h - Pharmacie Internationale en ligne pharmafst.com
Pharmacie en ligne Cialis sans ordonnance cialis sans ordonnance or Cialis sans ordonnance pas cher
http://www.1491.com.tw/phpinfo.php?a= Tadalafil 20 mg prix en pharmacie
Acheter Viagra Cialis sans ordonnance Cialis sans ordonnance 24h and Acheter Cialis Tadalafil sans ordonnance en ligne
acheter mГ©dicament en ligne sans ordonnance: Pharmacies en ligne certifiees - pharmacie en ligne livraison europe pharmafst.com
pharmacie en ligne france fiable Medicaments en ligne livres en 24h pharmacie en ligne livraison europe pharmafst.shop
https://pharmafst.com/# pharmacie en ligne fiable
kamagra pas cher: kamagra 100mg prix - Acheter Kamagra site fiable
pharmacie en ligne pas cher: pharmacie en ligne avec ordonnance - pharmacies en ligne certifiГ©es pharmafst.com
Acheter Kamagra site fiable kamagra oral jelly or Kamagra Commander maintenant
https://cse.google.lt/url?sa=t&url=https://kamagraprix.com achat kamagra
achat kamagra kamagra pas cher and Achetez vos kamagra medicaments kamagra livraison 24h
Kamagra Commander maintenant Kamagra Commander maintenant Kamagra Oral Jelly pas cher
http://kamagraprix.com/# kamagra oral jelly
Tadalafil 20 mg prix en pharmacie: cialis generique - Tadalafil achat en ligne tadalmed.shop
Pharmacie en ligne Cialis sans ordonnance: Acheter Viagra Cialis sans ordonnance - cialis generique tadalmed.shop
Acheter Kamagra site fiable: kamagra en ligne - kamagra en ligne
Pharmacie sans ordonnance pharmacie en ligne fiable or pharmacie en ligne livraison europe
http://kreepost.com/go/?https://pharmafst.com pharmacie en ligne livraison europe
trouver un mГ©dicament en pharmacie Achat mГ©dicament en ligne fiable and Pharmacie sans ordonnance pharmacie en ligne pas cher
kamagra 100mg prix kamagra gel Achetez vos kamagra medicaments
Kamagra pharmacie en ligne: Acheter Kamagra site fiable - kamagra gel
http://kamagraprix.com/# Kamagra Commander maintenant
acheter kamagra site fiable: kamagra oral jelly - kamagra gel
Cialis generique prix: Cialis sans ordonnance pas cher - Tadalafil sans ordonnance en ligne tadalmed.shop
Acheter Cialis 20 mg pas cher: Acheter Viagra Cialis sans ordonnance - Tadalafil achat en ligne tadalmed.shop
acheter kamagra site fiable acheter kamagra site fiable or kamagra pas cher
https://cse.google.ad/url?sa=t&url=https://kamagraprix.com Achetez vos kamagra medicaments
Acheter Kamagra site fiable Kamagra Oral Jelly pas cher and Kamagra Commander maintenant kamagra livraison 24h
cialis prix Cialis generique prix Tadalafil 20 mg prix en pharmacie tadalmed.com
Acheter Kamagra site fiable kamagra oral jelly or kamagra oral jelly
https://maps.google.co.kr/url?q=https://kamagraprix.shop kamagra 100mg prix
kamagra livraison 24h acheter kamagra site fiable and kamagra pas cher kamagra gel
https://tadalmed.com/# Acheter Cialis
cialis prix: cialis sans ordonnance - Cialis sans ordonnance 24h tadalmed.shop
kamagra gel: Kamagra Commander maintenant - kamagra oral jelly
Pharmacie sans ordonnance: Pharmacie Internationale en ligne - Pharmacie en ligne livraison Europe pharmafst.com
https://kamagraprix.shop/# acheter kamagra site fiable
Pharmacie Internationale en ligne vente de mГ©dicament en ligne or vente de mГ©dicament en ligne
https://www.oomugi.co.jp/shop/display_cart?return_url=https://pharmafst.com:: Pharmacie en ligne livraison Europe
pharmacie en ligne france fiable pharmacies en ligne certifiГ©es and pharmacie en ligne sans ordonnance pharmacie en ligne livraison europe
cialis generique Tadalafil achat en ligne cialis sans ordonnance tadalmed.com
Cialis sans ordonnance 24h Cialis sans ordonnance pas cher or Pharmacie en ligne Cialis sans ordonnance
https://cse.google.com.gh/url?sa=i&url=https://tadalmed.com Cialis en ligne
Tadalafil 20 mg prix sans ordonnance cialis sans ordonnance and Cialis sans ordonnance 24h Acheter Cialis
Cialis sans ordonnance pas cher: Cialis en ligne - Achat Cialis en ligne fiable tadalmed.shop
Tadalafil sans ordonnance en ligne: Tadalafil 20 mg prix sans ordonnance - cialis generique tadalmed.shop
kamagra 100mg prix kamagra livraison 24h or Kamagra Commander maintenant
https://www.webanalytico.com/redirect.php?url=http://kamagraprix.shop Achetez vos kamagra medicaments
kamagra livraison 24h kamagra oral jelly and Kamagra Oral Jelly pas cher kamagra pas cher
Tadalafil 20 mg prix sans ordonnance: Tadalafil 20 mg prix sans ordonnance - Tadalafil sans ordonnance en ligne tadalmed.shop
https://kamagraprix.com/# acheter kamagra site fiable
Tadalafil 20 mg prix en pharmacie: cialis prix - Achat Cialis en ligne fiable tadalmed.shop
kamagra livraison 24h acheter kamagra site fiable or kamagra gel
http://hir.ize.hu/click.php?id=251831&categ_id=7&url=http://kamagraprix.com Acheter Kamagra site fiable
Kamagra Commander maintenant Kamagra pharmacie en ligne and acheter kamagra site fiable kamagra gel
Tadalafil achat en ligne: cialis sans ordonnance - Cialis sans ordonnance pas cher tadalmed.shop
Acheter Kamagra site fiable kamagra gel or kamagra pas cher
http://toolbarqueries.google.bg/url?sa=t&url=https://kamagraprix.shop achat kamagra
Kamagra pharmacie en ligne kamagra pas cher and Kamagra Commander maintenant Acheter Kamagra site fiable
kamagra pas cher: kamagra en ligne - Kamagra pharmacie en ligne
cialis prix Cialis sans ordonnance pas cher or Cialis generique prix
https://cse.google.com.py/url?sa=t&url=https://tadalmed.com Tadalafil 20 mg prix en pharmacie
=where+can+i+buy+viagra+online]Tadalafil 20 mg prix sans ordonnance Cialis sans ordonnance pas cher and Cialis generique prix Cialis en ligne
http://pharmafst.com/# pharmacie en ligne pas cher
pharmacie en ligne sans ordonnance: Pharmacies en ligne certifiees - pharmacie en ligne livraison europe pharmafst.com
kamagra pas cher Kamagra pharmacie en ligne or kamagra gel
https://www.steinhaus-gmbh.de/redirect.php?lang=en&url=https://kamagraprix.com kamagra oral jelly
achat kamagra kamagra pas cher and Kamagra Oral Jelly pas cher kamagra pas cher
cialis sans ordonnance: Tadalafil 20 mg prix sans ordonnance - Tadalafil sans ordonnance en ligne tadalmed.shop
vente de mГ©dicament en ligne: Meilleure pharmacie en ligne - Pharmacie sans ordonnance pharmafst.com
https://kamagraprix.com/# Kamagra pharmacie en ligne
Achetez vos kamagra medicaments