Does anyone have WORKING oAuth LTI verification code written in PHP? My struggle is validating the oauth_signature that is being sent over from the Canvas LTI. I've tried several PHP libraries (OAuthSimple, etc.) with no luck. It generates the signature but it never lines up with what Canvas is sending. I've been able to validate my code using the lti.tools/oauth online tool so it appears that my path and SBS are correct but still not lining up with what Canvas sends over.
Does anyone know why this is? Every time I research this issue, it's just a bunch of links to a "possible answer". It never answers it. Ha! Very frustrating. So. Does anyone have WORKING code in PHP that I can use to validate my LTI call?
Neither of the institutions used php coding for #oauth authentication but I am going to share this over with https://community.canvaslms.com/groups/canvas-developers?sr=search&searchId=d165e359-8777-4e5c-943a-... group as I am sure there is someone in there can assist you.
Hello there, email@example.com...
I have been reviewing older questions here in the Canvas Community, and I came across your question. I noticed that there hasn't been any new activity in this topic since July 18, 2018. It seems that you may have stumped the Community with your question. Have you been able to find a solution on your own since you first posted this question back on March 30, 2018? If so, would you be willing to share what you have learned back here in this topic? Or, if you are still looking for some help with this question, please come back to this topic to post a message below so that someone from the Community might be able to assist you. I am going to mark your question s "Assumed Answered"...not because we've necessarily found an answer for you...but more because there hasn't been any new activity in this topic for about five months. However, that will not prevent you or others from posting additional questions and/or comments below that are related to this topic. I hope that's alright with you, David. Looking forward to hearing back from you soon.
I have been working on a working model. I have no update at this time but I have a good idea how I'm going to write it. I just have to get to it. I'm hope to present this and some other things at InstructureCon this year. We will see. More later I guess.
For anyone looking up this thread in the future, I managed to throw together a simple "proof of concept" using PHP's OAuth extension that seems to give the correct signature:
$method = $_SERVER['REQUEST_METHOD'];
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')
$protocol = 'https://';
else $protocol = 'http://';
$url = $protocol.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING'];
$params = $_REQUEST;
$oauth = new OAuth(CANVAS_KEY,CANVAS_SECRET);
$oauth->setTimestamp( $params['oauth_timestamp'] );
$oauth->setNonce( $params['oauth_nonce'] );
$oauth->setVersion( $params['oauth_version'] );
echo "Canvas signature: ".$_REQUEST['oauth_signature'];
echo "Signature verification: ".$oauth->generateSignature($method, $url, $params );
I've only tested this on a simple page call though, so it may not work in "all situations". Also note that even though this code fetches the method from REQUEST_METHOD, AFAIK Canvas will always use POST for LTI calls(?)
Not sure if adding QUERY_STRING will actually work properly either, some LTI/OAuth guides says that if there are GET parameters then they need to be used to generate the signature for it to be correct, but I'm not sure what cases would cause it to be GET parameters in the call. It's possible this is also never used in Canvas LTI calls.
I have a version (albeit messy) that will do similar as above - I'm storing the token in JS using localstorage.
Here's what I have:
$code = $_GET["code"];
$ch = curl_init();
$post = "grant_type=authorization_code&client_id=ID&client_secret=SECRET&redirect_uri=URI&code=" . $code;
curl_setopt($ch, CURLOPT_URL,"https://<canvas instance>/login/oauth2/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$json = json_decode($resp);
echo "localStorage.setItem('accessToken','" . $json->access_token . "');";
echo "localStorage.setItem('refreshToken','" . $json->refresh_token . "');";
Then I use the local storage in index.php - from here you can also generate new tokens too
I also use ajax on index.php to make api calls from there as it means I don't have to refresh the page if I want new data to be added to the page