Kenneth —
I've spent some time hacking together
some stuff around this exact issue in PHP. That said, I'll bet PHP isn't actually useful to you. ;) (I think I'm the only one in the Canvas-verse that actually uses it. wah-wah.)
But, here's the mental gymnastics that I went through to think about this. There are basically two choices that you can make here: either you just generate one set of admin credentials and masquerade as the users who are performing the actions (very pragmatic, very straight-forward… maybe not so secure?) OR you can embed an OAuth authorization in your LTI app's workflow (much like the
Google Apps LTI).
If you go the "masquerade as the user" route, then all you need is your own admin API access token and you will be sent the user's Canvas ID as the
custom_canvas_user_id parameter in the LTI request. This then allows you to add an
as_user_id=ID parameter to your API requests made with your own token to masquerade as the user (in theory, I suppose you could also use the
lis_person_sourcedid LTI request parameter and masquerade via SIS ID:
as_user_id=sis_user_id:ID).
If you go the OAuth route, then you'll need to do a check as a user enters your app workflow to see if you already have an API access token for that user. If not, you'll need to go through the
OAuth flow to request an API token (I imagine, whatever language you're using, there's a convenient framework for handling the OAuth workflow — and, in PHP, I've
extended the PHP League's OAuth 2.0 Client — the point is that the actual workflow is fiddly and easy to screw up). Once you receive the API access token for this user, you probably want to cache it somewhere, so that you can reuse it on subsequent visits. And then you can use the user's API token to make any API requests you need to make.
One thing that you'll want to be careful about as you do this is to make your API requests of the Canvas instance that sent you the original LTI request… and that's sent to you as the custom_canvas_api_domain parameter in the original LTI request. That way you can run actual tests on your test instance, rather than doing awful things to live data from your test instance (which can be upsetting, I find).
In general, my recommendation would be to bite the bullet and go with the OAuth request workflow, rather than the single token, for two basic reasons:
- It results in cleaner security settings (and less confusion) — masquerading sometimes doesn't work via the Canvas API — can't think of the specific examples at this moment, but I've definitely septa afternoons fighting a masqueraded API request that turns out not to accept masqueraded API requests, rather than being a permissions issue. If the API request doesn't work without masquerading, you know it's because of permissions. And, you aren't setting yourself up to, say, accidentally forget to masquerade and provide access to features beyond user's permission level by using your token. Plus, if your account is compromised, it doesn't trickle down to compromise everyone's account!
- It's a bit more transparent to the user too — they see that they are giving you access to do things in Canvas under their account (you provide a message explaining it as part of the OAuth flow) and then the access token is clearly labeled as your app when they look at their profile page.