I have my server create a shadow customer and get a claim_code for them, but I'm at a loss as to where to actually use the claim code when trying to claim a new device.
"Once the customer's device is connected to the Particle device's network, your mobile app then will send the claim code generated in the last step to the Particle device."
Just how will my mobile app send the claim code to my device?
Can I do it with the SparkSetupMainController system, or do I need to use the iOS SparkCloud api?
I agree, this seems to be a confusing spot in the documentation. I don’t see any methods in the SDK to inject the claim code to be used by the setup process. It would be great to get some guidance regarding this situation.
When you use the device setup SDK for iOS or Android you don’t need to obtain the claim code yourself.
There are two different behaviors implemented in the device setup SDK:
If you do not set the oAuthClientId and oAuthClientSecret a normal user account claim code is created and it’s associated with the user that is logged in, possibly just created, as occurs in the Particle phone apps.
If you do set the oAuthClientId, oAuthClientSecret, productMode and productId, then the product claiming endpoint is used instead. This generates a claim code for a given product and user using two-legged auth.
In either case, the device setup SDK obtains the claim code, then sends it to the Photon via SoftAP automatically. You don’t need to do anything.
The only time you need to generate and handle a claim code manually is if you are using a different method of configuring devices. For example, if you are using SoftAP directly, or a custom computer or phone app not using the device setup SDK.
Thanks for the quick response @rickkas7. I just want to clarify the second scenario you described. I think I might be confused.
From the documentation it sounded like the ClientId and Secret would be stored on our own server when doing two-legged authentication but from your scenario it sounds like it is provided on the device before starting the setup SDK. It was my impression from this page (https://docs.particle.io/guide/how-to-build-a-product/authentication/#two-legged-authentication) that the oAuth client credentials are stored on our own server and then the access token is passed back to the device after creating the new customer. Am I wrong in that assumption?
Sorry about that, I had simple auth on the brain when I answered that. I don’t believe the device setup SDK has a way to do that part of two-legged.
For two-legged, when you create the customer and claim code on your own server, you don’t want the authentication/account creation part of the device SDK.
Since getting the claim code from your server to your app will require something custom, that can’t be part of the device SDK.
The one part that would be useful would be the part about switching the Wi-Fi and sending the claim code to the device.
The other problem is that the device SDK monitors the event stream to see if the device comes online. That’s how it verifies claiming. But for two-legged, since the phone app doesn’t authenticate as the customer, it doesn’t have a customer-scoped access token, so it can’t monitor the event stream for the customer.
As far as I know you can’t do the network switching and claim code setting from the device SDK, though it would make sense to be able to do that step, I think.
So I think (more like hope) I am starting to piece these steps together. I went back and re-read Step 3 of the two legged authentication post I linked above and at the bottom of that step, it mentions injecting the Access token that is returned by the custom server after creating the “shadow customer” in the Particle system. Then it links to their github page with a section on injecting the access token:
I’m hoping with those instructions, combined with setting skipAuthentication=true in the spark setup controller, that it will allow the user to configure the wifi for the device as well as claim a new device without asking them to login and will link to the shadow customer I am creating via my server.
I’ll post back here again after some testing and let you know what i find out.
Thank you for finding that. I tried it and indeed it works just as you’d hope.
The key is that you need to inject the customer access token, not the claim code, using injectSessionAccessToken.
@IBAction func startDeviceSetup(_ sender: Any) {
SparkCloud.sharedInstance().injectSessionAccessToken("7d6453e063710ea474d7da43919e15ce2fbe3757");
if let setupController = SparkSetupMainController()
{
if let c = SparkSetupCustomization.sharedInstance()
{
c.productMode = true;
c.productName = "Temperature Monitor";
c.productId = 1319;
c.allowSkipAuthentication = true;
}
setupController.delegate = self
self.present(setupController, animated: true, completion: nil)
}
}
By injecting the customer’s access token, the device setup SDK is able to generate a claim code for that two-legged customer, use it to claim the device, and also monitor the correct event stream to verify ownership. Works great!
Obviously you wouldn’t hardcode the customer access token like that. It’s specific to a given customer and only valid for an hour, so your app would do something to communicate with your server to generate a new customer instead of doing that.