Trouble getting Authorization Code programatically
Moderators: StaffingSupport, s.emmons, BullhornSupport
-
- User
- Posts: 2
- Joined: Wed Jan 10, 2018 11:29 am
Trouble getting Authorization Code programatically
Hello Support - hopefully someone can help me out here, as I've been banging my head against this brick wall for a couple of days.
I cannot for the live of me figure out how to get this code programatically. I can get the code just fine in Postman after manually logging in, but not in the browser or via code.
https://auth.bullhornstaffing.com/oauth ... _type=code
&redirect_uri={optional redirect_uri}&state={recommended state value}&username={username}&password={password}&action=Login is the URL I am trying to use.
If I just do the basic URL without the login action and I manually login via the browser (https://auth.bullhornstaffing.com/oauth ... _type=code) I get this error "Authorization Code not received", but there is a callback code in the URL at that time.
However, using Postman and logging in when prompted spits out a code just fine. I just need this process automated!
I am using PHP for my code. Any help would be greatly appreciated, this is urgent and I am struggling!
I cannot for the live of me figure out how to get this code programatically. I can get the code just fine in Postman after manually logging in, but not in the browser or via code.
https://auth.bullhornstaffing.com/oauth ... _type=code
&redirect_uri={optional redirect_uri}&state={recommended state value}&username={username}&password={password}&action=Login is the URL I am trying to use.
If I just do the basic URL without the login action and I manually login via the browser (https://auth.bullhornstaffing.com/oauth ... _type=code) I get this error "Authorization Code not received", but there is a callback code in the URL at that time.
However, using Postman and logging in when prompted spits out a code just fine. I just need this process automated!
I am using PHP for my code. Any help would be greatly appreciated, this is urgent and I am struggling!
Re: Trouble getting Authorization Code programatically
Hi, since you are able to run the API authorisation successfully but are having issues translating this into an automated PHP process Bullhorn Support would not be able to assist with this.
Apologies that I could not provide you with an answer, I would suggest that perhaps a PHP forum would better serve your needs.
Apologies that I could not provide you with an answer, I would suggest that perhaps a PHP forum would better serve your needs.
Bullhorn Support UK: 44 800 032 2848
Bullhorn Support US: 1 617-478-9126
Bullhorn Support Australia: 61 28 073 5089
Bullhorn Support International: 1 617-478-9131
Bullhorn Support US: 1 617-478-9126
Bullhorn Support Australia: 61 28 073 5089
Bullhorn Support International: 1 617-478-9131
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Any progress yet?
The secret is to use the curl -V url in the docs and make sure:
1) you don't follow the redirect, and
2) you get headers.
In my codebase that means I have to make sure:
The code is in the initial response but not in the redirect (which is usually http://www.bullhorn.com).
Step 1:
So set your curl options to not follow redirects, then parse the response and take the substring before the HTML stuff starts. That substring holds the headers.
Then parse your headers to pull out the code.
I use the following:
And then I use the code to ask for a refresh token using the next step (Step 2):
You're going to get back a response with an access token and a refresh token.
Store the refresh token for the next login (so you don't have to go through the authorize process again) and the access token to use immediately.
Step 3:
That call gets you your BhRestToken which you can attach to all subsequent calls to validate your login. When it expires, just use the refresh token to ask for another access token (Step 4):
That returns you an access token, so you can go back to step 3 with your new access token and get a new BhRestToken.
That process took me a long time to get right, but as long as I have proper credentials from my client (client_id, client_secret, username, password) I just plug in the right values and don't think about logging in any more.
I'm coming back to this code because I'm setting up a new client. Hopefully this post is helpful.
Dave Block
North Creek Consulting, Inc.
The secret is to use the curl -V url in the docs and make sure:
1) you don't follow the redirect, and
2) you get headers.
In my codebase that means I have to make sure:
Code: Select all
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_MAXREDIRS, 0);
curl_setopt($ch, CURLOPT_HEADER=>true);
Step 1:
Code: Select all
https://auth.bullhornstaffing.com/oauth/authorize?client_id={client_id}&response_type=code
&redirect_uri={optional redirect_uri}&state={recommended state value}&username={username}&password={password}&action=Login
Then parse your headers to pull out the code.
I use the following:
Code: Select all
//...$authResponse is what I get back from calling Step 1 via curl...
$html_start = strpos($authResponse, '<!DOCTYPE html>');
$headers = substr($authResponse, 0, $html_start);
if (preg_match("|Location: (https?://\S+)|", $headers, $m)) {
//Location is in $m[1]
if (preg_match("|code=(\S+)\&client_id|", $m[1], $n)) {
$code = urldecode($n[1]);
Code: Select all
https://auth.bullhornstaffing.com/oauth/token?grant_type=authorization_code&code={auth_code}&client_id={client_id}&client_secret={client_secret}&redirect_uri={optional redirect_uri}
Store the refresh token for the next login (so you don't have to go through the authorize process again) and the access token to use immediately.
Step 3:
Code: Select all
https://rest.bullhornstaffing.com/rest-services/login?version=2.0&access_token={xxxxxxxx}
Code: Select all
https://auth.bullhornstaffing.com/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}&client_id={client_id}&client_secret={client_secret}
That process took me a long time to get right, but as long as I have proper credentials from my client (client_id, client_secret, username, password) I just plug in the right values and don't think about logging in any more.
I'm coming back to this code because I'm setting up a new client. Hopefully this post is helpful.
Dave Block
North Creek Consulting, Inc.
Re: Trouble getting Authorization Code programatically
Dave,
Are you sure that this method is still working? It seems like for the most part as far as the auth code it's the right idea, but for some reason, it doesn't seem to work. Curl does return what you're outlining, but the headers don't contain relevant info, and it's actually returning the HTML to the consent page. Does that sound about right? This isn't terribly well documented other than a couple lines in the docs.
--John
Are you sure that this method is still working? It seems like for the most part as far as the auth code it's the right idea, but for some reason, it doesn't seem to work. Curl does return what you're outlining, but the headers don't contain relevant info, and it's actually returning the HTML to the consent page. Does that sound about right? This isn't terribly well documented other than a couple lines in the docs.
--John
-
- User
- Posts: 3
- Joined: Thu Mar 29, 2018 1:30 pm
Re: Trouble getting Authorization Code programatically
I am having the same issue fcdjohn is talking about. The documentation makes it seem as if one should expect a json response with the auth code but it instead returns html.
Re: Trouble getting Authorization Code programatically
Has anyone been able to get this to work? I cannot get the authorization code programmtically before of the consent form.
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Hi people,
I've been working on non-Bullhorn projects for the past while, but I'm back at the coal face. It does seem like there have been changes, so I'll post what works as I fight through authorization with a new client here in this thread.
I tend to cheat if I can get through manually and steal the tokens from the URL - but I'll let you know if I can get that to work.
Dave
North Creek
Back into the Bullhorn World right now
I've been working on non-Bullhorn projects for the past while, but I'm back at the coal face. It does seem like there have been changes, so I'll post what works as I fight through authorization with a new client here in this thread.
I tend to cheat if I can get through manually and steal the tokens from the URL - but I'll let you know if I can get that to work.
Dave
North Creek
Back into the Bullhorn World right now
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
First issue with this client - I had to get my IP whitelisted with Bullhorn. That will be awkward as we move from my test box to staging, to production, but hopefully it won't take long to add an IP to an account somewhere.
Bullhorn Support- is there a way a customer can add their developer's IP address to their account somewhere so this step doesn't have to go through you?
Bullhorn Support- is there a way a customer can add their developer's IP address to their account somewhere so this step doesn't have to go through you?
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Got some help from support - my client is in the EMEA zone, so I had to add that to the urls (auth-emea and rest-emea) and I was able to get a manual login to the point where I got an authorization code.
The next step is to use the code to get an access token using
(straight from the docs).
This is returning me
(using auth-emea instead of auth in the url).
I'll keep updating here as I make progress.
It really appears they have shut down the automated login uri.
The next step is to use the code to get an access token using
Code: Select all
https://auth.bullhornstaffing.com/oauth/token?grant_type=authorization_code&code={auth_code}&client_id={client_id}&client_secret={client_secret}&redirect_uri={optional redirect_uri}
This is returning me
Code: Select all
[
["error"]=>
string(13) "invalid_grant"
["error_description"]=>
string(48) "Invalid, expired, or revoked authorization code."
]
I'll keep updating here as I make progress.
It really appears they have shut down the automated login uri.
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Okay, I'm now able to log in (using the manual step to log in initially, and then storing the auth code I received from that step).
The issue was the difference between the automatic login (where I was extracting the code from the data I received via curl in PHP) and the manual login (copy and paste from the browser bar).
In the manual step, I copied directly the code, and it had been url-encoded. Once I url-decoded the supplied code, it was accepted and I was able to carry on and log in.
A support ticket has been generated through my client about the loss of the automated login workflow. I will update the forum with the result of that query.
In the meantime, if you copy/paste the code from the browser bar, remember to urldecode it!
Happy coding!
Dave
North Creek
The issue was the difference between the automatic login (where I was extracting the code from the data I received via curl in PHP) and the manual login (copy and paste from the browser bar).
In the manual step, I copied directly the code, and it had been url-encoded. Once I url-decoded the supplied code, it was accepted and I was able to carry on and log in.
A support ticket has been generated through my client about the loss of the automated login workflow. I will update the forum with the result of that query.
In the meantime, if you copy/paste the code from the browser bar, remember to urldecode it!
Happy coding!
Dave
North Creek
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Over the weekend my auth code expired, so the code did what it was programmed to do and tried to get a new auth code programatically.
As we seem to have confirmed, that option seems to have been removed and so I needed to log in manually again in order to get a new auth code.
Thankfully, after my previous work, that auth code was good enough to restart the rest of the process and so my client's code is back running again.
*This is a problem, Bullhorn*. We can't have clients who depend on our integration code having to manually log in every 2-3 weeks in order to use the REST API.
I will be asking my client to open up a support ticket asking for a better resolution to this.
As we seem to have confirmed, that option seems to have been removed and so I needed to log in manually again in order to get a new auth code.
Thankfully, after my previous work, that auth code was good enough to restart the rest of the process and so my client's code is back running again.
*This is a problem, Bullhorn*. We can't have clients who depend on our integration code having to manually log in every 2-3 weeks in order to use the REST API.
I will be asking my client to open up a support ticket asking for a better resolution to this.
-
- User
- Posts: 89
- Joined: Fri Nov 20, 2015 2:04 pm
Re: Trouble getting Authorization Code programatically
Curiouser and curiouser.
I was able to get a code from the following URI:
once I added in the redirect_uri parameter.
I got the expected headers
But supplying this {NEW_CODE} to the next step
got me the following response:
According to this post from 5 years ago:
viewtopic.php?f=104&t=14309&p=56385&hil ... uri#p56385
I can just remove the redirect_uri parameter from the request and things will work, but as I said at the beginning, the redirect_uri parameter was the missing piece that got the whole process to work.
****SO, I felt like I was back at square one, but I must have missed something*****
I ran the whole thing again without the redirect URI, and the problem was that my code was looking for a valid HTML body, but the change was that the server returns this:
I had been looking for <!DOCTYPE html> as a signifier of the end of the headers but this 502 connection refused was just going straight to <HEAD>.
I changed my code to look for '<' (since there are no angle brackets in a valid header, right?) and everything started working again.
So it looks like the big change that messed me up (and apparently not only me) was the change in the response HTML away from the DOCTYPE declaration to just <HEAD>.
Handcrafted code is fragile - I will keep reporting if this breaks again.
I was able to get a code from the following URI:
Code: Select all
https://auth-emea.bullhornstaffing.com/oauth/authorize?client_id={CLIENT_ID}&response_type=code&redirect_uri=http%3A%2F%2Fwww.bullhorn.com&state=random_string&username={USERNAME}&password={PASSWORD}&action=Login
I got the expected headers
Code: Select all
HTTP/1.1 301 Moved Permanently
Content-Type: text/html
Date: Mon, 11 Jun 2018 15:36:07 GMT
Location: https://www.bullhorn.com/?code={NEW_CODE}&client_id={CLIENT_ID}&state=random_string
Code: Select all
https://auth-emea.bullhornstaffing.com/oauth/token?code=22%3A2c3fbe53-f268-44dd-adad-3366162852eb&client_id=cfa052e4-9556-44fd-88ad-43731c92fe6c&client_secret=rsAMtUcMcW2lnc1S2s9dLgxr&grant_type=authorization_code
Code: Select all
[2018-06-11 09:36:19] local.DEBUG: array(2) {
["error"]=>
string(13) "invalid_grant"
["error_description"]=>
string(22) "Mismatch redirect uri."
}
viewtopic.php?f=104&t=14309&p=56385&hil ... uri#p56385
I can just remove the redirect_uri parameter from the request and things will work, but as I said at the beginning, the redirect_uri parameter was the missing piece that got the whole process to work.
****SO, I felt like I was back at square one, but I must have missed something*****
I ran the whole thing again without the redirect URI, and the problem was that my code was looking for a valid HTML body, but the change was that the server returns this:
Code: Select all
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID={REDACTED}; Path=/oauth/; HttpOnly
Location: http://auth-emea.bullhornstaffing.com/oauth/207.228.78.97?code={CODE}&client_id={CLIENT_ID}&state=random_string
Content-Length: 0
Date: Mon, 11 Jun 2018 15:49:17 GMT
HTTP/1.1 502 Connection refused
Date: Mon, 11 Jun 2018 15:49:17 GMT
Connection: close
Cache-Control: no-store
Content-Type: text/html
Content-Language: en
Content-Length: 213
<HEAD><TITLE>Connection refused</TITLE></HEAD>
<BODY BGCOLOR="white" FGCOLOR="black">
<FONT FACE="Helvetica,Arial"><B>
Connection refused</B></FONT>
<!-- default "Connection refused" response (502) -->
</BODY>
I changed my code to look for '<' (since there are no angle brackets in a valid header, right?) and everything started working again.
So it looks like the big change that messed me up (and apparently not only me) was the change in the response HTML away from the DOCTYPE declaration to just <HEAD>.
Handcrafted code is fragile - I will keep reporting if this breaks again.