/admin/users/sync_sso ... Route not found

Any idea why I’m getting this when trying to issue a POST request?

ActionController::RoutingError (No route matches [POST] “/admin/users/sync_sso”)


Well the route is that one.

Are you passing api_username and api_key as query params too?


I am. Here is the code block. This is the exact say thing I’m doing in my SSO login route. Only difference is obviously the URI.

     const sso = new DiscourseSSO(SSOKey);
            const nonce = 'dummy data';
            const userparams = {
              external_id: user._id.toString(),
              email: user.email,
              username: user.username.replace(/\s/g, ''),
            const q = sso.buildLoginString(userparams);
            fetch('https://community.testsite.com/admin/users/sync_sso', { method: 'POST', body: q })
              .then(res => res.json())
              .then(json => console.log(json));

You aren’t passing api_username and api_key.

You need those as query params.

You can check our #howto in the topic here: Sync SSO user data with the sync_sso route


sso.buildLoginString is doing that.

discourse_sso.prototype.buildLoginString = function(params) {
	if(!("external_id" in params)) {
		throw new Exception("Missing required parameter 'external_id'");
	if(!("nonce" in params)) {
		throw new Exception("Missing required parameter 'nonce'");
	if(!("email" in params)) {
		throw new Exception("Missing required parameter 'email'");
	var payload = new Buffer( querystring.stringify(params) , 'utf8').toString("base64");
	var hmac = this.getHmac();
	return querystring.stringify({
		'sso': payload,
		'sig': hmac.digest('hex')

Using this node package for SSO login. Which works perfectly. Trying to repurpose that for this …


Where? I don’t see api_username and api_key anywhere.

1 Like

Right. I was adding in as form data before. Here is the updated. Still getting the Route Not Found error in the rails logs though.

 const userparams = {
          api_username: someusername,
          api_key: somekey,
          external_id: user._id.toString(),
          email: user.email,
          username: user.username.replace(/\s/g, ''),

Code that produces the bottom query:

const userparams = {
      external_id: user._id.toString(),
      email: user.email,
      username: user.username.replace(/\s/g, ''),
    const payload = new Buffer(querystring.stringify(userparams), 'utf8').toString('base64');
    const hmac = crypto.createHmac('sha256', DiscourseSSOKey);
    const query = querystring.stringify({
      sso: payload,
      sig: hmac.digest('hex'),
      api_username: UserName,
      api_key: API Key,
    fetch('https://community.somesite.com/admin/users/sync_sso', {
      method: 'POST',
      body: query,
      .then(res => res.json())
      .then(json => console.log(json));    

Here’s the query that gets generated and passed as the body on the POST route:


This all still gives me a Route Not Found error in the rails logs.

Any thoughts on the above? Does that look right?

You’re delivering the wrong Content-Type. Try providing the object directly as the body to fetch, without querystring.stringify.

also, hang on a sec, i’m going to let you finish, but URLSearchParams is the best browser api of 2016


The api_* parameters need to be in the query parameters, not the POST body.

So you need something like:

fetch('https://community.testsite.com/admin/users/sync_sso?api_username=USERNAME&api_key=KITTENS', { method: 'POST', body: body })

Ah understood. So the api_username and api_key in the query parameters and the rest in the post body.

They can also be in the body

All my Postman requests have them in the body:

Unless this route is special?


It’s not. The WordPress plugin sends the api parameters for the sync_sso route in the body of the request: https://github.com/discourse/wp-discourse/blob/master/lib/sso-provider/discourse-sso.php#L329


That’s correct, the problem was sending the wrong body type so the api_username/api_key couldn’t be parsed out.



I am attemping the SSO sync but getting the no route found error. Im trying via postman.
I have tried adding the key and username both in the body and as request params, but same result.

any ideas?

could you elaborate on this… if using postman, what headers/values need to be set?

The Content-Type should be “multipart/form-data”, but I don’t think you have to set that in the header if the Body is already set to “form-data” (my Headers in Postman are all blank).

hmmm, theres not much in the logs to highlight where the issue is…
failing that, is it most likely the payload and sig thats the problem?

For testing this, im doing the following:

  1. taking the following payload string:

  2. Generating the base64 encoded payload via:

  3. Taking that payload and generating the hmac-Sha256 encryped payload via:
    Free Online HMAC Generator / Checker Tool (MD5, SHA-256, SHA-512) - FreeFormatter.com

  4. Then sticking them both in postman, sso=payload, sig=encrypted payload

  5. I have generated an API key for user ‘system’ and passing that in with the body.

Error i get in discourse logs:

Started POST “/discussion/admin/users/sync_sso” for at 2018-05-24 15:45:08 +0000

ActionController::RoutingError (No route matches [POST] “/admin/users/sync_sso”)

/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/debug_exceptions.rb:63:in `call’

Rendering text template