|
48 | 48 |
|
49 | 49 | // ErrTokenAccessKey is error for invalid access_token
|
50 | 50 | ErrTokenAccessKey = errors.New("goic id_token: invalid access_token")
|
| 51 | + |
| 52 | + // ErrSignOutRedir is error for invalid post sign-out redirect uri |
| 53 | + ErrSignOutRedir = errors.New("goic sign-out: post redirect uri is invalid") |
51 | 54 | )
|
52 | 55 |
|
53 | 56 | var (
|
@@ -421,6 +424,44 @@ func (g *Goic) RefreshToken(tok *Token) (*Token, error) {
|
421 | 424 | return t, err
|
422 | 425 | }
|
423 | 426 |
|
| 427 | +// SignOut signs out the Token from OpenID Provider and then redirects to given URI |
| 428 | +// Redirect URI must be preconfigured in OpenID Provider already |
| 429 | +func (g *Goic) SignOut(tok *Token, redir string, res http.ResponseWriter, req *http.Request) error { |
| 430 | + if redir != "" { |
| 431 | + if _, err := url.Parse(redir); err != nil { |
| 432 | + return ErrSignOutRedir |
| 433 | + } |
| 434 | + } |
| 435 | + |
| 436 | + name := tok.Provider |
| 437 | + if !g.Supports(name) { |
| 438 | + return ErrProviderSupport |
| 439 | + } |
| 440 | + |
| 441 | + tk := tok.AccessToken |
| 442 | + if tk == "" && tok.RefreshToken != "" { |
| 443 | + tk = tok.RefreshToken |
| 444 | + } else { |
| 445 | + return ErrTokenAccessKey |
| 446 | + } |
| 447 | + |
| 448 | + p := g.providers[tok.Provider] |
| 449 | + redirect, err := http.NewRequest("GET", p.wellKnown.SignOutURI, nil) |
| 450 | + if err != nil { |
| 451 | + return err |
| 452 | + } |
| 453 | + |
| 454 | + qry := redirect.URL.Query() |
| 455 | + qry.Add("id_token_hint", tk) |
| 456 | + if redir != "" { |
| 457 | + qry.Add("post_logout_redirect_uri", redir) |
| 458 | + } |
| 459 | + |
| 460 | + redirect.URL.RawQuery = qry.Encode() |
| 461 | + http.Redirect(res, req, redirect.URL.String(), http.StatusFound) |
| 462 | + return nil |
| 463 | +} |
| 464 | + |
424 | 465 | // logIf logs if verbose is set
|
425 | 466 | func (g *Goic) logIf(s string, v ...interface{}) {
|
426 | 467 | if g.verbose {
|
|
0 commit comments