HTTP 401(Unauthorized), 403(Forbidden) 차이

2021. 6. 20. 21:39γ†πŸŒ Web

 

4xx λŒ€ μ—λŸ¬λŠ” ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ 잘λͺ»λœ μš”μ²­(request)을 λ³΄λƒˆμ„ λ•Œ λ°œμƒν•˜λŠ” μ—λŸ¬μž…λ‹ˆλ‹€. κ·Έ 쀑 401 μ—λŸ¬μ™€ 403 μ—λŸ¬λŠ” λͺ¨λ‘ 인증이 μ•ˆλμ„ λ•Œ λ°œμƒν•˜λŠ”λ°, 이 차이λ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

1. 401 Unauthorized μ—λŸ¬

- HTTP μƒνƒœ μ—λŸ¬ 쀑 401은, ν΄λΌμ΄μ–ΈνŠΈκ°€ μΈμ¦λ˜μ§€ μ•Šμ•˜μ„ λ•Œ λ°œμƒν•˜λŠ” μ—λŸ¬μž…λ‹ˆλ‹€. μΈμ¦λ˜μ§€ μ•Šμ€ κ²½μš°λž€, μ‰½κ²Œ 말해 λ‘œκ·ΈμΈμ„ ν•˜μ§€ μ•Šμ•˜μ„ λ•Œ, μ–΄λ ΅κ²Œ 말해 request 헀더에 μœ νš¨ν•œ 인증 정보가 ν¬ν•¨λ˜μ§€ μ•Šμ•˜μ„ λ•Œλ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. 즉 ν΄λΌμ΄μ–ΈνŠΈκ°€ ν•΄λ‹Ή μš”μ²­μ— κΆŒν•œμ΄ 없을 λ•Œ, 이λ₯Ό κΈˆμ§€(Forbidden)μ‹œν‚€λŠ” μ—λŸ¬μž…λ‹ˆλ‹€. μš°λ¦¬κ°€ ν”νžˆ 둜그인 ν•˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ 글을 μž‘μ„±ν•˜κ±°λ‚˜ λ§ˆμ΄νŽ˜μ΄μ§€λ₯Ό μ‘°νšŒν•˜λ €κ³  ν•  λ•Œ μ„œλ²„λŠ” 401 μ—λŸ¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

AccessToken 없이 HTTP Patch μš”μ²­μ„ 보내면, status().isUnauthorized() λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

    @Test
    void updateUserWithoutAccessToken() throws Exception {
        mockMvc.perform(
                patch("/users/1")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"name\":\"TEST\",\"password\":\"test\"}")
        )
                .andExpect(status().isUnauthorized());
    }
    

 

 

2. 403 Forbidden μ—λŸ¬

- 403 μ—λŸ¬λŠ”, μ„œλ²„κ°€ μš”μ²­(request)을 μ΄ν•΄λŠ” ν–ˆμ§€λ§Œ, ν•΄λ‹Ή μš”μ²­μ„ κ±°λΆ€ν•  λ•Œ λ°œμƒν•©λ‹ˆλ‹€. 즉 λ‘œκ·ΈμΈμ€ ν–ˆμ§€λ§Œ κΆŒν•œ λ°–μ˜ 일을 μˆ˜ν–‰ν•  λ•Œ, 예λ₯Ό λ“€μ–΄ λ‹€λ₯Έ μ‚¬λžŒμ˜ λŒ“κΈ€μ„ μˆ˜μ •ν•˜κ±°λ‚˜ μ‚­μ œν•  λ•Œ λ°œμƒν•˜λŠ” μ—λŸ¬(403 Forbidden) μž…λ‹ˆλ‹€. λ‹Ήμ—°νžˆ μ„œλ²„λŠ” μž‘μ„±μž 본인의 κΈ€λ§Œ μˆ˜μ •/μ‚­μ œν•  수 μžˆλ„λ‘ μ œμ–΄λ₯Ό ν•΄μ•Όκ² μ£ . 

 

AccessToken을 request에 ν¬ν•¨ν•˜μ—¬ 보내더라도, μœ νš¨ν•˜μ§€ μ•Šμ€ AccessToken,

즉 λ‹€λ₯Έ μ‚¬λžŒμ˜ AccessToken 이라면, updateκ°€ λΆˆκ°€λŠ₯ν•˜λ„λ‘ status().isForbidden() 을 좜λ ₯ν•©λ‹ˆλ‹€.

    @Test
    void updateUserWithOthersAccessToken() throws Exception {
        mockMvc.perform(
                patch("/users/1")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"name\":\"TEST\",\"password\":\"test\"}")
                        .header("Authorization", "Bearer " + OTHER_TOKEN)
        )
                .andExpect(status().isForbidden());
    }

 

 

μΆ”κ°€) Authentication, Authorization 차이

인증(authentication)κ³Ό κΆŒν•œ(authorization)에 λŒ€ν•΄μ„œλ„ μΆ”κ°€λ‘œ λ‹€λ€„λ΄…μ‹œλ‹€. Apache  κ³΅μ‹λ¬Έμ„œμ—λŠ” μ•„λž˜μ™€ 같이 Authenticationκ³Ό authorization을 μ„€λͺ…ν•©λ‹ˆλ‹€.

 

"인증(authentication)은 μžμ‹ μ΄ λˆ„κ΅¬λΌκ³  μ£Όμž₯ν•˜λŠ” μ‚¬λžŒμ„ ν™•μΈν•˜λŠ” μ ˆμ°¨μ΄λ‹€. κΆŒν•œλΆ€μ—¬(authorization)λŠ” κ°€κ³  싢은 곳으둜 가도둝 ν˜Ήμ€ μ›ν•˜λŠ” 정보λ₯Ό 얻도둝 ν—ˆμš©ν•˜λŠ” 과정이닀." 

ν’€μ–΄μ„œ μ–˜κΈ°ν•˜μžλ©΄, Authentication은 곧 둜그인의 과정이고, Authorization은 둜그인 ν›„, ν•΄λ‹Ή μœ μ €κ°€ κ΄€λ¦¬μžμΈμ§€ 일반 μ‚¬μš©μžμΈμ§€ κ΅¬λΆ„ν•˜λŠ” μ ˆμ°¨μž…λ‹ˆλ‹€.