I have an existing rails app that is using devise as it's user authentication. I added a discourse forum and everything went smoothly and it resides on a subdomain. I have read the post at https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045 but still don't know what to do with the devise side of things once the user logs in on the existing rails site. Currently this is the process as I understand it:
Step1: User hits Discourse forum on subdomain. User needs to login so clicks login button.
Step2: User is sent to the login page on the existing rails site.
Step3: User logs in on rails site.
Step4: User should be redirected to discourse forum subdomain logged in.
My question is - What do I need to to do to make it so that when a user logs in on step 3 they get redirected back to the subdomain? Has anyone successfully implemented this? I saw this code snippet on that walkthrough page:
class DiscourseSsoController < ApplicationController
def sso
secret = "MY_SECRET_STRING"
sso = SingleSignOn.parse(request.query_string, secret)
sso.email = "[email protected]"
sso.name = "Bill Hicks"
sso.username = "[email protected]"
sso.external_id = "123" # unique to your application
sso.sso_secret = secret
redirect_to sso.to_url("http://l.discourse/session/sso_login")
end
end
Is this what I would need to add in my existing rails app? I'm guessing the parse checks if that information is in the url and if so it redirects once it finishes the devise login process, and if not it just functions as usual. Would I place this code somewhere in the devise files?
This is pretty straightforward. Following on from the instructions at https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045 and extrapolating a little, I have this working:
1) Put the reference implementation - https://github.com/discourse/discourse/blob/master/lib/single_sign_on.rb - in your #{Rails.root}/lib directory
2) Add this route to routes.rb
get 'discourse/sso' => 'discourse_sso#sso'
3) Put this controller in your app/controllers directory
require 'single_sign_on'
class DiscourseSsoController < ApplicationController
before_action :authenticate_user! # ensures user must login
def sso
secret = "MY_SECRET_STRING"
sso = SingleSignOn.parse(request.query_string, secret)
sso.email = current_user.email # from devise
sso.name = current_user.full_name # this is a custom method on the User class
sso.username = current_user.email # from devise
sso.external_id = current_user.id # from devise
sso.sso_secret = secret
redirect_to sso.to_url("http://your_discource_server/session/sso_login")
end
end
4) Set up the SSO config in discourse to have the following
sso url: http://your_rails_server/discourse/sso
sso secret : what you set as MY_SECRET_STRING above
5) Disable other login types in discourse.
6) Try to login in discourse. It should work...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With