Closed strk closed 7 years ago
It looks like a fork does have the code to add the info: https://github.com/kushaldas/openid.go/commit/4c3f26a6e719dfe71d2eeb86143c9dc83568ac97
Would you be interested in pulling that in ? Maybe exposing a VerifyFull ?
@kushaldas any reason not to send a PR yourself ?
I took a look at the code in @kushaldas repo. I don't really like the fact that it's in Verify. I think it'd be better to keep the two things separated (handling whatever values are passed to you in the URL, which are not in the OpenID specs AFAIK, and verifying that the assertion in the URL is correct)
Your code already calls Verify with the URL, so why not just parse the info you want out of it, after calling Verify to make sure all checks out of course?
I know, the URL gets parsed twice, but I think that shouldn't be such a big deal.
I haven't found that info in the parameters passed to the callback, so dunno where GNUSocial is getting them (nor the fork commit).
I surely don't like the interface change (of Verify method) but maybe adding a VerifyFull would fix that ?
It wouldn't really help you if the info is not in the URL.
The Verify function from the above link only has the info you pass to it. If openid.sreg.email
is not in the callback URL, his implementation is not going to find it.
@kushaldas's repo Verify function gets the various info from the URL:
func verify(uri string, ...) {
parsedUrl, err := url.Parse(uri)
// ...
values, err := url.ParseQuery(parsedUrl.RawQuery)
// ...
m["email"] = values.Get("openid.sreg.email")
// ...
return m, nil
}
And you are calling verify directly with the uri
string. So you can do the same thing in your code as well.
From the example in this repo, instead of
func callbackHandler(w http.ResponseWriter, r *http.Request) {
fullUrl := "http://localhost:8080" + r.URL.String()
id, err := openid.Verify(fullUrl, discoveryCache, nonceStore)
// ...
}
You would do:
func callbackHandler(w http.ResponseWriter, r *http.Request) {
fullUrl := "http://localhost:8080" + r.URL.String()
id, err := openid.Verify(fullUrl, discoveryCache, nonceStore)
if err == nil {
parsedUrl, err := url.Parse(uri)
values, err := url.ParseQuery(parsedUrl.RawQuery)
email := values.Get("openid.sreg.email")
// And now you have an email
// ...
}
}
(plus various error handling)
I'm guessing maybe you need to request this info when you first redirect to the provider's URL?
Ok, now I see. GNUSocial adds parameters to the OP call, namely:
openid.sreg.optional=nickname%2Cemail%2Cfullname%2Clanguage%2Ctimezone%2Cpostcode%2Ccountry
So I need a way to pass RedirectURL these custom parameters, right ?
Could be. You should be able to test it by just appending it to the URL generated by RedirectURL.
Yeah, maybe try to add it here: https://github.com/yohcop/openid-go/blob/master/redirect.go#L25
If that works, we can think about how to pass a set of url.Values
to the BuildRedirectURL function!
Yep, adding to the return from RedirectURL did it:
url += "&openid.sreg.optional=nickname%2Cemail"
Some support function to make encoding that easier could be useful
Anyway, the question was answered, so closing this. Thanks!
Now though, the openid.sreg.optional
field only worked against a SimpleID
provider, failing with both GNUSocial
and openid.stackexchange.com
:(
I've filed the GNUSocial issue upstream: https://git.gnu.io/gnu/gnu-social/issues/243 But I'm not sure it's my code rather than theirs...
The go package net/url should have everything you need to encode URL parameters.
Do they have this documented somewhere? (i.e. that adding those parameters should result in a callback with the right values?) Since both URLs end up in your browser's address bar (the redirect, and the callback), it's pretty easy to see where the problem is.
If you redirect to the right URL, the callback should have the expected values. If you don't construct the redirect URL right (escaping for example), you should also see it in your browser.
Figured, I had to also pass &openid.ns.sreg=http%3A%2F%2Fopenid.net%2Fextensions%2Fsreg%2F1.1
for the stackexchange and GNUSocial support.
GNUSocial now also returns nickname/email while openid.stackexchange.com only returns email (but I think stackexchange simply doesn't have a concept of "nickname").
@yohcop documentation of the extension (Simple Registration Extension) is here: https://openid.net/specs/openid-simple-registration-extension-1_0.html
My OID provider provides nickname/email, and I know it's working because GNUSocial is able to retrive them. How do I retrive them with openid-go ?