mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Allow for PKCE flow without client secret + add docs (#25033)
The PKCE flow according to [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) allows for secure authorization without the requirement to provide a client secret for the OAuth app. It is implemented in Gitea since #5378 (v1.8.0), however without being able to omit client secret. Since #21316 Gitea supports setting client type at OAuth app registration. As public clients are already forced to use PKCE since #21316, in this PR the client secret check is being skipped if a public client is detected. As Gitea seems to implement PKCE authorization correctly according to the spec, this would allow for PKCE flow without providing a client secret. Also add some docs for it, please check language as I'm not a native English speaker. Closes #17107 Closes #25047
This commit is contained in:
		@@ -120,6 +120,29 @@ func TestAccessTokenExchange(t *testing.T) {
 | 
			
		||||
	assert.True(t, len(parsed.RefreshToken) > 10)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestAccessTokenExchangeWithPublicClient(t *testing.T) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
	req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
 | 
			
		||||
		"grant_type":    "authorization_code",
 | 
			
		||||
		"client_id":     "ce5a1322-42a7-11ed-b878-0242ac120002",
 | 
			
		||||
		"redirect_uri":  "http://127.0.0.1",
 | 
			
		||||
		"code":          "authcodepublic",
 | 
			
		||||
		"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
 | 
			
		||||
	})
 | 
			
		||||
	resp := MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	type response struct {
 | 
			
		||||
		AccessToken  string `json:"access_token"`
 | 
			
		||||
		TokenType    string `json:"token_type"`
 | 
			
		||||
		ExpiresIn    int64  `json:"expires_in"`
 | 
			
		||||
		RefreshToken string `json:"refresh_token"`
 | 
			
		||||
	}
 | 
			
		||||
	parsed := new(response)
 | 
			
		||||
 | 
			
		||||
	assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), parsed))
 | 
			
		||||
	assert.True(t, len(parsed.AccessToken) > 10)
 | 
			
		||||
	assert.True(t, len(parsed.RefreshToken) > 10)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestAccessTokenExchangeJSON(t *testing.T) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
	req := NewRequestWithJSON(t, "POST", "/login/oauth/access_token", map[string]string{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user