I followed this tutorial to set up authentication with JWT and devise https://www.sitepoint.com/introduction-to-using-jwt-in-rails/. My authentication_controller looks like this:
class AuthenticationController < ApplicationController
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
private
def payload(user)
return nil unless user && user.id
{
auth_token: JsonWebToken.encode({user_id: user.id}),
user: {id: user.id, email: user.email}
}
end
end
It maps to a route called auth_user, as shown here in my routes.rb file:
Rails.application.routes.draw do
resources :reviews
resources :people do
resources :reviews
end
post 'auth_user' => 'authentication#authenticate_user'
devise_for :users, :controllers => {sessions: 'sessions', registrations:
'registrations'}
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
All my other routes work, including posting to the devise routes, but this one give a 500 internal server error. Any ideas of what could be causing this behavior are greatly appreciated! For what its worth, I'm on Rails 5.1.5, JWT 2.1.0, and Devise 4.4.3. Thanks!
I checked the heroku logs after trying to send a request. They look like this:
2018-04-26T20:53:32.801349+00:00 app[web.1]: I, [2018-04-26T20:53:32.801222 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Started POST "/auth_user" for 199.116.73.196 at 2018-04-26 20:53:32 +0000
2018-04-26T20:53:32.824053+00:00 app[web.1]: I, [2018-04-26T20:53:32.823923 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Processing by AuthenticationController#authenticate_user as */*
2018-04-26T20:53:32.824188+00:00 app[web.1]: I, [2018-04-26T20:53:32.824119 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Parameters: {"email"=>"\"mike#mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T20:53:32.953483+00:00 app[web.1]: D, [2018-04-26T20:53:32.953329 #4] DEBUG -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] [1m[36mUser Load (8.4ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["email", "\"mike#mike.com\""], ["LIMIT", 1]]
2018-04-26T20:53:32.963709+00:00 app[web.1]: I, [2018-04-26T20:53:32.963569 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Completed 500 Internal Server Error in 139ms (ActiveRecord: 53.2ms)
2018-04-26T20:53:32.964567+00:00 app[web.1]: F, [2018-04-26T20:53:32.964492 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964715+00:00 app[web.1]: F, [2018-04-26T20:53:32.964649 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] NoMethodError (undefined method `valid_password?' for nil:NilClass):
2018-04-26T20:53:32.964805+00:00 app[web.1]: F, [2018-04-26T20:53:32.964742 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964904+00:00 app[web.1]: F, [2018-04-26T20:53:32.964844 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] app/controllers/authentication_controller.rb:4:in `authenticate_user'
2018-04-26T20:53:32.966716+00:00 heroku[router]: at=info method=POST path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com request_id=bb58b729-4d79-4940-b73d-2bc433c8d224 fwd="199.116.73.196" dyno=web.1 connect=1ms service=172ms status=500 bytes=203 protocol=https
Still a bit baffled as to what's breaking, but at least it's clear now where the problem is!
Change the code in authenticate_user to this:
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user && user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
Now I get the expected json response for if the user was not found, but if I input the data for a valid user it does not give the proper response. Could this be a problem with the find_for_database_authentication method? The logs now show this:
2018-04-26T21:24:07.327940+00:00 heroku[router]: at=info method=POST
path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com
request_id=95dcfdd7-55d5-4a24-b8e4-d597737c4b02 fwd="199.116.73.196"
dyno=web.1 connect=1ms service=15ms status=401 bytes=286 protocol=https
2018-04-26T21:24:07.319101+00:00 app[web.1]: I, [2018-04-26T21:24:07.318981
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Started POST
"/auth_user" for 199.116.73.196 at 2018-04-26 21:24:07 +0000
2018-04-26T21:24:07.320412+00:00 app[web.1]: I, [2018-04-26T21:24:07.320296
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Processing by
AuthenticationController#authenticate_user as */*
2018-04-26T21:24:07.320476+00:00 app[web.1]: I, [2018-04-26T21:24:07.320410
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Parameters:
{"email"=>"\"mike#mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T21:24:07.329226+00:00 app[web.1]: D, [2018-04-26T21:24:07.328689
#4] DEBUG -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] [1m[36mUser Load
(5.1ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email"
=
$1 LIMIT $2[0m [["email", "\"mike#mike.com\""], ["LIMIT", 1]]
2018-04-26T21:24:07.330108+00:00 app[web.1]: I, [2018-04-26T21:24:07.330005
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02]
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash
(0.17ms)
2018-04-26T21:24:07.330482+00:00 app[web.1]: I, [2018-04-26T21:24:07.330370
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Completed 401
Unauthorized in 10ms (Views: 1.0ms | ActiveRecord: 5.1ms)
Looking at your logs, I see:
NoMethodError (undefined method `valid_password?' for nil:NilClass):
This probably coming from the line:
user.valid_password?(params[:password])
Which means your user variable is nil. This is happening because user = User.find_for_database_authentication(email: params[:email]) is returning nil.
Check to see if your user exists in the database by running the rails console, using heroku run rails c. If not, create it, and your code should work fine.
I am attempting to connect Amazon S3 to my site so to store user avatars. I expect users to be able to add an avatar to their profiles, but it seems that I am denied access. I've looked at and tried several solutions with no success:
Ruby Amazon S3 Access Denied when listing buckets
How to solve “Access Denied” with Heroku + Paperclip + S3 + ROR
Uploading to S3 With Paperclip
Error message:
AWS::S3::Errors::AccessDenied: Access Denied File "/app/app/controllers/profiles_controller.rb", line 13 in create
Full Trace:
2016-02-03T23:30:12.826846+00:00 app[web.1]: Rendered pages/home.html.erb within layouts/application (1.3ms)
2016-02-03T23:30:12.830420+00:00 app[web.1]: Completed 200 OK in 9ms (Views: 6.1ms | ActiveRecord: 1.2ms)
2016-02-03T23:30:12.821127+00:00 app[web.1]: Processing by PagesController#home as HTML
2016-02-03T23:30:12.830151+00:00 app[web.1]: Rendered layouts/_header.html.erb (0.9ms)
2016-02-03T23:30:12.824076+00:00 app[web.1]: Plan Load (0.5ms) SELECT "plans".* FROM "plans" WHERE "plans"."name" = 'mentee' LIMIT 1
2016-02-03T23:31:23.614411+00:00 app[web.1]: Processing by ProfilesController#create as HTML
2016-02-03T23:31:23.618346+00:00 app[web.1]: User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 32 ORDER BY "users"."id" ASC LIMIT 1
2016-02-03T23:31:23.621171+00:00 app[web.1]: CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "32"]]
2016-02-03T23:31:23.642828+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]' 2>/dev/null
2016-02-03T23:31:23.731583+00:00 app[web.1]: Command :: convert '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]' -auto-orient -resize "300x300>" '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex620160203-3-zkzzqj'
2016-02-03T23:31:23.610892+00:00 app[web.1]: Started POST "/users/32/profile" for 108.80.140.163 at 2016-02-03 23:31:23 +0000
2016-02-03T23:31:23.615000+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"ArxGVYON7jf+nRR9HfMcpHWxSgk4uHIw7ELCnDaJhvc=", "profile"=>{"not_available"=>"0", "first_name"=>"Kim", "last_name"=>"Crayton", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fe496024c48 #tempfile=#<Tempfile:/tmp/RackMultipart20160203-3-1nmybbz>, #original_filename="Kim Crayton.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"profile[avatar]\"; filename=\"Kim Crayton.jpg\"\r\nContent-Type: image/jpeg\r\n">, "contact_email"=>"kimmcrayton#gmail.com", "city"=>"Atlanta", "state"=>"GA", "country"=>"USA", "coding_languages"=>"HTML, CSS, JavaScript, Python", "bio"=>"I was an educator, writer, and researcher in another life who decided to dive into the coding end of the pool. I've learned the basics on my own and like most who want to swim in the Olympics, I need a good coach to get me to the next level.", "mentoring_needs"=>"To be able to level up my skill set to become employed as a Jr. Developer"}, "commit"=>"Update Profile", "user_id"=>"32"}
2016-02-03T23:31:23.620344+00:00 app[web.1]: User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 32]]
2016-02-03T23:31:23.629345+00:00 app[web.1]: Command :: file -b --mime '/tmp/7ad9d08462a928e43510aef94b436bb820160203-3-1p8wtua.jpg'
2016-02-03T23:31:23.717450+00:00 app[web.1]: Command :: identify -format %m '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]'
2016-02-03T23:31:24.346558+00:00 app[web.1]: Command :: file -b --mime '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex620160203-3-zkzzqj'
2016-02-03T23:31:24.468671+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]' 2>/dev/null
2016-02-03T23:31:25.276211+00:00 app[web.1]: Command :: identify -format %m '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]'
2016-02-03T23:31:25.356070+00:00 app[web.1]: Command :: convert '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex6.jpg[0]' -auto-orient -resize "100x100>" '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex620160203-3-6j3feu'
2016-02-03T23:31:25.933442+00:00 app[web.1]: Command :: file -b --mime '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-oy7ex620160203-3-6j3feu'
2016-02-03T23:31:25.968535+00:00 app[web.1]: (1.8ms) BEGIN
2016-02-03T23:31:26.011723+00:00 app[web.1]: SQL (1.9ms) INSERT INTO "profiles" ("avatar_content_type", "avatar_file_name", "avatar_file_size", "avatar_updated_at", "bio", "city", "coding_languages", "contact_email", "country", "created_at", "first_name", "last_name", "mentoring_needs", "state", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING "id" [["avatar_content_type", "image/jpeg"], ["avatar_file_name", "Kim_Crayton.jpg"], ["avatar_file_size", 588778], ["avatar_updated_at", "2016-02-03 23:31:23.627122"], ["bio", "I was an educator, writer, and researcher in another life who decided to dive into the coding end of the pool. I've learned the basics on my own and like most who want to swim in the Olympics, I need a good coach to get me to the next level."], ["city", "Atlanta"], ["coding_languages", "HTML, CSS, JavaScript, Python"], ["contact_email", "kimmcrayton#gmail.com"], ["country", "USA"], ["created_at", "2016-02-03 23:31:26.002769"], ["first_name", "Kim"], ["last_name", "Crayton"], ["mentoring_needs", "To be able to level up my skill set to become employed as a Jr. Developer"], ["state", "GA"], ["updated_at", "2016-02-03 23:31:26.002769"], ["user_id", 32]]
2016-02-03T23:31:25.965320+00:00 app[web.1]: Profile Load (8.5ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT 1 [["user_id", 32]]
2016-02-03T23:31:26.012791+00:00 app[web.1]: [paperclip] saving /profiles/avatars/000/000/024/original/Kim_Crayton.jpg
2016-02-03T23:31:25.972587+00:00 app[web.1]: Command :: file -b --mime '/tmp/7ad9d08462a928e43510aef94b436bb820160203-3-1fkobfh.jpg'
2016-02-03T23:31:26.192049+00:00 app[web.1]: [AWS S3 403 0.176059 0 retries] put_object(:acl=>:public_read,:bucket_name=>"BUCKET_NAME_VALUE",:content_length=>588778,:content_type=>"image/jpeg",:data=>Paperclip::UploadedFileAdapter: Kim Crayton.jpg,:key=>"profiles/avatars/000/000/024/original/Kim_Crayton.jpg") AWS::S3::Errors::AccessDenied Access Denied
2016-02-03T23:31:26.192052+00:00 app[web.1]:
2016-02-03T23:31:26.199059+00:00 app[web.1]: (5.4ms) ROLLBACK
2016-02-03T23:31:26.239693+00:00 app[web.1]: Completed 500 Internal Server Error in 2625ms
2016-02-03T23:31:26.278651+00:00 app[web.1]: [Rollbar] Scheduling payload
2016-02-03T23:31:26.278749+00:00 app[web.1]: [Rollbar] Sending payload
2016-02-03T23:31:26.255527+00:00 app[web.1]: [Rollbar] Reporting exception: Access Denied
2016-02-03T23:31:26.565131+00:00 heroku[router]: at=info method=POST path="/users/32/profile" host=www.jrdevmentoring.com request_id=39b4d6a4-de82-4746-bba2-15326511c36c fwd="108.80.140.163" dyno=web.1 connect=0ms service=5691ms status=500 bytes=1754
2016-02-03T23:31:26.556786+00:00 app[web.1]: [Rollbar] Success
2016-02-03T23:31:26.556867+00:00 app[web.1]: [Rollbar] Details: https://rollbar.com/instance/uuid?uuid=e2c97cca-326f-4501-a1ac-dabcedc8d047 (only available if report was successful)
2016-02-03T23:31:26.556955+00:00 app[web.1]: [Rollbar] Exception uuid saved in env: e2c97cca-326f-4501-a1ac-dabcedc8d047
2016-02-03T23:31:26.562072+00:00 app[web.1]:
2016-02-03T23:31:26.562074+00:00 app[web.1]: app/controllers/profiles_controller.rb:13:in `create'
2016-02-03T23:31:26.562075+00:00 app[web.1]:
2016-02-03T23:31:26.562074+00:00 app[web.1]: AWS::S3::Errors::AccessDenied (Access Denied):
2016-02-03T23:31:26.562075+00:00 app[web.1]:
2016-02-03T23:32:23.939135+00:00 heroku[router]: at=info method=GET path="/users/32/profile/new" host=www.jrdevmentoring.com request_id=a926abfc-e512-42cc-bcf0-b49f0e660051 fwd="108.80.140.163" dyno=web.1 connect=0ms service=22ms status=304 bytes=844
2016-02-03T23:32:23.921568+00:00 app[web.1]: Parameters: {"user_id"=>"32"}
2016-02-03T23:32:23.921563+00:00 app[web.1]: Processing by ProfilesController#new as HTML
2016-02-03T23:32:23.924214+00:00 app[web.1]: User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 32 ORDER BY "users"."id" ASC LIMIT 1
2016-02-03T23:32:23.926869+00:00 app[web.1]: CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "32"]]
2016-02-03T23:32:23.934672+00:00 app[web.1]: Rendered profiles/_form.html.erb (5.2ms)
2016-02-03T23:32:23.934795+00:00 app[web.1]: Rendered profiles/new.html.erb within layouts/mentee_layout (5.5ms)
2016-02-03T23:32:23.935958+00:00 app[web.1]: Rendered layouts/_header.html.erb (0.4ms)
2016-02-03T23:32:23.919293+00:00 app[web.1]: Started GET "/users/32/profile/new" for 108.80.140.163 at 2016-02-03 23:32:23 +0000
2016-02-03T23:32:23.926294+00:00 app[web.1]: User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 32]]
2016-02-03T23:32:23.936324+00:00 app[web.1]: Completed 200 OK in 15ms (Views: 8.2ms | ActiveRecord: 2.5ms)
2016-02-03T23:32:23.928924+00:00 app[web.1]: Plan Load (0.7ms) SELECT "plans".* FROM "plans" WHERE "plans"."id" = $1 LIMIT 1 [["id", 30]]
2016-02-03T23:32:24.067025+00:00 heroku[router]: at=info method=GET path="/assets/application-ccf1b63ef283bc859fc20d775228d578.js" host=www.jrdevmentoring.com request_id=fd39d73a-d506-4b69-ac11-042db1ca8cee fwd="108.80.140.163" dyno=web.1 connect=0ms service=16ms status=304 bytes=133
2016-02-03T23:32:24.051947+00:00 heroku[router]: at=info method=GET path="/assets/application-9750215382cdb39b0d4756e6b205dd25.css" host=www.jrdevmentoring.com request_id=7f1972d5-75f3-469c-9672-2d149981a9b9 fwd="108.80.140.163" dyno=web.1 connect=0ms service=8ms status=304 bytes=133
2016-02-03T23:32:28.231345+00:00 app[web.1]: User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 32]]
2016-02-03T23:32:28.222520+00:00 app[web.1]: Started POST "/users/32/profile" for 108.80.140.163 at 2016-02-03 23:32:28 +0000
2016-02-03T23:32:28.367338+00:00 app[web.1]: Command :: identify -format %m '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]'
2016-02-03T23:32:28.240793+00:00 app[web.1]: Command :: file -b --mime '/tmp/7ad9d08462a928e43510aef94b436bb820160203-3-133toy1.jpg'
2016-02-03T23:32:28.225432+00:00 app[web.1]: Processing by ProfilesController#create as HTML
2016-02-03T23:32:28.225555+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"ArxGVYON7jf+nRR9HfMcpHWxSgk4uHIw7ELCnDaJhvc=", "profile"=>{"not_available"=>"0", "first_name"=>"Kim", "last_name"=>"Crayton", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x007fe496024c48 #tempfile=#<Tempfile:/tmp/RackMultipart20160203-3-spce1k>, #original_filename="Kim Crayton.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"profile[avatar]\"; filename=\"Kim Crayton.jpg\"\r\nContent-Type: image/jpeg\r\n">, "contact_email"=>"kimmcrayton#gmail.com", "city"=>"Atlanta", "state"=>"GA", "country"=>"USA", "coding_languages"=>"HTML, CSS, JavaScript, Python", "bio"=>"I was an educator, writer, and researcher in another life who decided to dive into the coding end of the pool. I've learned the basics on my own and like most who want to swim in the Olympics, I need a good coach to get me to the next level.", "mentoring_needs"=>"To be able to level up my skill set to become employed as a Jr. Developer"}, "commit"=>"Update Profile", "user_id"=>"32"}
2016-02-03T23:32:28.229747+00:00 app[web.1]: User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 32 ORDER BY "users"."id" ASC LIMIT 1
2016-02-03T23:32:28.232006+00:00 app[web.1]: CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "32"]]
2016-02-03T23:32:28.411553+00:00 app[web.1]: Command :: convert '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]' -auto-orient -resize "300x300>" '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf20160203-3-bep14i'
2016-02-03T23:32:28.254571+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]' 2>/dev/null
2016-02-03T23:32:29.005396+00:00 app[web.1]: Command :: file -b --mime '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf20160203-3-bep14i'
2016-02-03T23:32:29.215235+00:00 app[web.1]: Command :: identify -format %m '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]'
2016-02-03T23:32:29.042851+00:00 app[web.1]: Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]' 2>/dev/null
2016-02-03T23:32:29.254140+00:00 app[web.1]: Command :: convert '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf.jpg[0]' -auto-orient -resize "100x100>" '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf20160203-3-18abmic'
2016-02-03T23:32:29.899670+00:00 app[web.1]: Command :: file -b --mime '/tmp/907d62dfd370e834d14b2f9e69569f8f20160203-3-150cqxf20160203-3-18abmic'
2016-02-03T23:32:29.934163+00:00 app[web.1]: SQL (1.0ms) INSERT INTO "profiles" ("avatar_content_type", "avatar_file_name", "avatar_file_size", "avatar_updated_at", "bio", "city", "coding_languages", "contact_email", "country", "created_at", "first_name", "last_name", "mentoring_needs", "state", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING "id" [["avatar_content_type", "image/jpeg"], ["avatar_file_name", "Kim_Crayton.jpg"], ["avatar_file_size", 588778], ["avatar_updated_at", "2016-02-03 23:32:28.238610"], ["bio", "I was an educator, writer, and researcher in another life who decided to dive into the coding end of the pool. I've learned the basics on my own and like most who want to swim in the Olympics, I need a good coach to get me to the next level."], ["city", "Atlanta"], ["coding_languages", "HTML, CSS, JavaScript, Python"], ["contact_email", "kimmcrayton#gmail.com"], ["country", "USA"], ["created_at", "2016-02-03 23:32:29.931498"], ["first_name", "Kim"], ["last_name", "Crayton"], ["mentoring_needs", "To be able to level up my skill set to become employed as a Jr. Developer"], ["state", "GA"], ["updated_at", "2016-02-03 23:32:29.931498"], ["user_id", 32]]
2016-02-03T23:32:29.983370+00:00 app[web.1]: [AWS S3 403 0.044695 0 retries] put_object(:acl=>:public_read,:bucket_name=>"BUCKET_NAME_VALUE",:content_length=>588778,:content_type=>"image/jpeg",:data=>Paperclip::UploadedFileAdapter: Kim Crayton.jpg,:key=>"profiles/avatars/000/000/025/original/Kim_Crayton.jpg") AWS::S3::Errors::AccessDenied Access Denied
2016-02-03T23:32:29.989703+00:00 app[web.1]: [Rollbar] Reporting exception: Access Denied
2016-02-03T23:32:29.918738+00:00 app[web.1]: (3.9ms) BEGIN
2016-02-03T23:32:29.985462+00:00 app[web.1]: (1.0ms) ROLLBACK
2016-02-03T23:32:29.913438+00:00 app[web.1]: Profile Load (1.0ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT 1 [["user_id", 32]]
2016-02-03T23:32:29.983374+00:00 app[web.1]:
2016-02-03T23:32:29.935107+00:00 app[web.1]: [paperclip] saving /profiles/avatars/000/000/025/original/Kim_Crayton.jpg
2016-02-03T23:32:29.920674+00:00 app[web.1]: Command :: file -b --mime '/tmp/7ad9d08462a928e43510aef94b436bb820160203-3-9amf8x.jpg'
2016-02-03T23:32:29.986839+00:00 app[web.1]: Completed 500 Internal Server Error in 1761ms
2016-02-03T23:32:30.038337+00:00 app[web.1]: [Rollbar] Sending payload
2016-02-03T23:32:30.035794+00:00 app[web.1]: [Rollbar] Scheduling payload
2016-02-03T23:32:30.297265+00:00 app[web.1]: [Rollbar] Success
2016-02-03T23:32:30.298549+00:00 app[web.1]: [Rollbar] Exception uuid saved in env: fe95e497-18b6-4711-8141-94789670b5ed
2016-02-03T23:32:30.312149+00:00 app[web.1]: app/controllers/profiles_controller.rb:13:in `create'
2016-02-03T23:32:30.312147+00:00 app[web.1]: AWS::S3::Errors::AccessDenied (Access Denied):
2016-02-03T23:32:30.298468+00:00 app[web.1]: [Rollbar] Details: https://rollbar.com/instance/uuid?uuid=fe95e497-18b6-4711-8141-94789670b5ed (only available if report was successful)
2016-02-03T23:32:30.312144+00:00 app[web.1]:
2016-02-03T23:32:30.312149+00:00 app[web.1]:
2016-02-03T23:32:30.312150+00:00 app[web.1]:
2016-02-03T23:32:30.317622+00:00 heroku[router]: at=info method=POST path="/users/32/profile" host=www.jrdevmentoring.com request_id=6930043a-4007-4c13-9a38-0cac82aac0b6 fwd="108.80.140.163" dyno=web.1 connect=0ms service=4641ms status=500 bytes=1754
2016-02-03T23:41:43.818611+00:00 heroku[router]: at=info method=GET path="/" host=www.jrdevmentoring.com request_id=05a31e30-d8d1-465e-9a0d-4a545668949a fwd="107.206.188.61" dyno=web.1 connect=0ms service=58ms status=200 bytes=3069
2016-02-03T23:41:43.800534+00:00 app[web.1]: Started GET "/" for 107.206.188.61 at 2016-02-03 23:41:43 +0000
2016-02-03T23:41:43.808750+00:00 app[web.1]: Plan Load (1.4ms) SELECT "plans".* FROM "plans" WHERE "plans"."name" = 'mentor' LIMIT 1
2016-02-03T23:41:43.815175+00:00 app[web.1]: Completed 200 OK in 9ms (Views: 4.7ms | ActiveRecord: 2.0ms)
2016-02-03T23:41:43.812975+00:00 app[web.1]: Rendered pages/home.html.erb within layouts/application (1.0ms)
2016-02-03T23:41:43.805782+00:00 app[web.1]: Processing by PagesController#home as HTML
2016-02-03T23:41:43.810095+00:00 app[web.1]: Plan Load (0.6ms) SELECT "plans".* FROM "plans" WHERE "plans"."name" = 'mentee' LIMIT 1
2016-02-03T23:41:43.814699+00:00 app[web.1]: Rendered layouts/_header.html.erb (0.5ms)
2016-02-03T23:41:44.007715+00:00 heroku[router]: at=info method=GET path="/assets/application-ccf1b63ef283bc859fc20d775228d578.js" host=www.jrdevmentoring.com request_id=8a323d54-7eb3-4f09-bbb2-cc1f245654bf fwd="107.206.188.61" dyno=web.1 connect=1ms service=20ms status=200 bytes=142105
2016-02-03T23:41:44.113132+00:00 heroku[router]: at=info method=GET path="/assets/application-9750215382cdb39b0d4756e6b205dd25.css" host=www.jrdevmentoring.com request_id=198cd717-23b5-413d-8903-9d5f944884e0 fwd="107.206.188.61" dyno=web.1 connect=0ms service=23ms status=200 bytes=114067
profiles_controller.rb
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :only_current_user
def new
# form where a user can fill out their own profile.
#user = User.find( params[:user_id] )
#profile = Profile.new
end
def create
#user = User.find( params[:user_id] )
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile Updated!"
redirect_to user_path( #user )
else
flash[:danger] = "An error occurred and your profile has not been updated. You must complete all form fields."
render action: :new
end
end
def edit
#user = User.find( params[:user_id] )
#profile = #user.profile
end
def update
#user = User.find( params[:user_id] )
#profile = #user.profile
if #profile.update_attributes(profile_params)
flash[:success] = "Profile Updated!"
redirect_to user_path( params[:user_id] )
else
render action: :edit
end
end
private
def profile_params
params.require(:profile).permit(:not_available, :first_name, :last_name, :avatar, :contact_email, :city, :state, :country, :coding_languages, :bio, :mentoring_needs)
end
def only_current_user
#user = User.find( params[:user_id] )
redirect_to(root_url) unless #user == current_user
end
end
production.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['S3_BUCKET_NAME'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
validates :first_name, presence: true
validates :last_name, presence: true
validates :contact_email, presence: true
validates :bio, presence: true
validates :mentoring_needs, presence: true
validates_length_of :coding_languages, minimum: 1, maximum: 500
validates_length_of :bio, minimum: 1, maximum: 1000
validates_length_of :mentoring_needs, minimum: 1, maximum: 500
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
As noted in a comment by user taglia
You need to set your AWS credentials as config variables in heroku (basically environment variables). You can check if they are set with heroku config; if they are not set, you can add them with heroku config:set S3_BUCKET_NAME=something AWS_ACCESS_KEY_ID=whatever AWS_SECRET_ACCESS_KEY=something_secret. More info with heroku config --help
I had this same problem after AWS changed their policy to require an IAM user. I created the new IAM user and received new credentials for the IAM user, and after updating my app with the new credentials, I received this same error. I fixed it by going back to AWS, Services, IAM User, and creating a permission for the user to have AdministratorAccess.