webView
Web지식 공부) session
코코넛딩
2024. 6. 22. 16:23
세션이란?
- 세션 이란?
- 서버와 클라이언트(사용자)간의 상호작용 상태를 유지하는 방법
- 세션은 사용자가 웹을 방문한 순간부터 떠나는 시점까지 상태 정보를 저장한다.
- 이 정보는 서버에서 관리하며, 고유한 세션ID를 통해 식별된다.
- 세션의 중요성
- 로그인
- 로그인 상태 유지 가능, 세션이 없다면 페이지 마다 로그인을 해줘야한다.
- 로그인 할 때 세션을 생성하고 이후의 요청마다 세션ID를 확인하여 사용자의 신원을 확인한다.
- 사용자가 이전에 방문했던 페이지, 설정, 진행 상황등을 기억한다.
- 로그인
- 세션의 작동방식
- 세션 생성
- 사용자가 로그인하거나 웹 애플리케이션을 처음 방문하면, 서버는 고유한 세션ID를 생성하고 이를 클라이언트에 전달
- 클라이언트는 이 세션ID를 쿠키에 저장하거나 URL 파라미터로 유지
- 세션ID를 쿠키에 저장하는 이유
- 자동 관리
- 웹 브라우저는 쿠키를 자동으로 관리하며 도메인에 따라 쿠키를 자동으로 포함시켜 요청을 보낸다.
- 이를 통해 서버는 세션을 유지하고 사용자의 상태를 추적할 수 있다.
- 보안
- 쿠키는 http(s) 전송 중에 자동으로 전송되기 때문에 URL 파라미터에 비해 덜 노출된다.
- URL
- 자동 관리
- 웹뷰나 웹이 직접 쿠키에 저장하면 안되는 이유
- 보안 문제
- javascript로 쿠키를 직접 설정하면 XSS(교차 사이트 스크립팅)공격에 세션ID가 탈취 당할 수 있다.
- 네이티브에서 안전하게 세션ID를 저장할 수 있는 방법을 제공
- sharedPreferences, keychain
- 보안 문제
- 세션ID를 쿠키에 저장하는 이유
- 세션 유지
- 사용자가 서버에 요청을 보낼때 마다 세션 ID가 함께 전송됩니다.
- 서버는 이 세션 ID를 사용하여 사용자의 상태 정보를 확인하고, 필요한 데이터를 제공
- 세션 종료
- 로그아웃할때나 세션 타임아웃(서버에서 설정 한다.)이 발생하면 세션이 종료된다.
- 세션이 종료되면 서버는 세션 정보를 삭제하고 사용자의 상태는 초기화된다.
- 세션 생성
- 앱을 꺼도 세션을 유지하는 방법
- 세션 복구 방식
- 세션 토큰 사용
- 세션 ID를 단순히 저장하고 사용하는 것보다, 더 안전한 방식으로 세션 토큰을 사용하는 것이 일반적이다.
- 세션 토큰은 사용자가 앱을 다시 열 때 서버에 제공되어, 사용자가 다시 로그인 하지 않고도 세션을 복구할 수 있습니다.
- 세션 토큰은 일반적으로 보안이 강화된 방식으로 생성되며, 만료시간( 개발자가 정함, 만료 시간은 일반적인 만료 시간)과 함께 사용된다.
- jwt(JSON Web Token) 토큰
- JWT는 사용자의 인증 상태를 나타내는 토큰이다.
- JWT는 JWT는 클라이언트 측에서 안전하게 저장되고, 서버와의 통신 시 인증을 위해 사용된다.
- JWT는 서버 측에서 사용자의 세션 상태를 저장할 필요가 없기 때문에 스케일링이 용이
- 세션 토큰 사용
- 세션 복구 방식
iOS WKWebView 세션 유지 어려운 이유
1. WKWebView의 쿠키
- 쿠키 관리 문제
- WKWebView는 UIWebView와 달리 쿠키 관리를 별도로 처리하기 때문에 세션 쿠키가 제대로 저장되지 않거나 웹뷰 간에 공유되지 않는 문제가 발생할 수 있다.
- 해결 방법
- WKHTTPCookieStore를 통해 쿠키를 관리
- 쿠키를 수동으로 설정하고 관리하여 세션 유지를 할 수 있다.
- 쿠키 설정시 고려사항
- 쿠키를 설정할 때 쿠키가 특정 경로에만 유효하도록 설정되어있다면 해당 경로를 벗어나면 쿠키가 유효하지 않다.
- 만약 모든 경로에 쿠키가 유효하도록 하려면 경로를 '/'로 설정하세요
- WKHTTPCookieStore를 통해 쿠키를 관리
import WebKit
let webView = WKWebView()
// 쿠키 설정 예시
let cookie = HTTPCookie(properties: [
.domain: "your-domain.com",
.path: "/",
.name: "your-cookie-name",
.value: "your-cookie-value",
.secure: "TRUE",
.expires: NSDate(timeIntervalSinceNow: 31556926)
])!
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
2. WKWebView 여러 인스턴스간의 세션 유지
- 공유 데이터 스토어 설정
- WKWebView의 여러 인스턴스가 동일한 WKWebsiteDataStore를 사용하도록 설정하면 세션 데이터를 공유할 수 있다.
- 쿠키 직접 설정 및 관리
- WKWebsiteDataStore에 직접 넣어줄 쿠키를 세팅하고 여러 웹뷰 인스턴스에 WKWebViewConfigurtation()에 dataStore를 설정해준다.
- dataStore에는 싱글턴 인스턴스가 들어있어서 여러 웹뷰 안에 넣어주기 편하다. 굳이 같은 변수를 넣어줄 필요가 없다.
import WebKit
func setCookie() {
// 쿠키 속성 정의
let cookie = HTTPCookie(properties: [
.domain: "your-domain.com",
.path: "/",
.name: "your-cookie-name",
.value: "your-cookie-value",
.secure: "TRUE",
.expires: NSDate(timeIntervalSinceNow: 31556926) // 쿠키 만료 시간 설정
])!
// 기본 웹사이트 데이터 저장소에서 쿠키 스토어 가져오기
let dataStore = WKWebsiteDataStore.default()
dataStore.httpCookieStore.setCookie(cookie) {
print("Cookie set successfully")
}
}
import UIKit
import WebKit
class WebViewController: UIViewController {
var webView1: WKWebView!
var webView2: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// 공통 WKWebsiteDataStore 생성
let dataStore = WKWebsiteDataStore.default()
// 첫 번째 웹뷰 생성 및 설정
let config1 = WKWebViewConfiguration()
config1.websiteDataStore = dataStore
webView1 = WKWebView(frame: .zero, configuration: config1)
// 두 번째 웹뷰 생성 및 설정
let config2 = WKWebViewConfiguration()
config2.websiteDataStore = dataStore
webView2 = WKWebView(frame: .zero, configuration: config2)
// 웹뷰 추가 및 레이아웃 설정
view.addSubview(webView1)
view.addSubview(webView2)
// 레이아웃 설정 예시
webView1.translatesAutoresizingMaskIntoConstraints = false
webView2.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
webView1.leadingAnchor.constraint(equalTo: view.leadingAnchor),
webView1.trailingAnchor.constraint(equalTo: view.trailingAnchor),
webView1.topAnchor.constraint(equalTo: view.topAnchor),
webView1.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5),
webView2.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- 페이지 로드 될때 마다 쿠키 복사해서 다른 WKWebView에 전달하기
func copyCookies(from sourceWebView: WKWebView, to targetWebView: WKWebView) {
sourceWebView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
for cookie in cookies {
targetWebView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
}
}
// 웹뷰 로드 완료 후 쿠키 복사
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
copyCookies(from: webView1, to: webView2)
}
안드로이드 WebView 세션 유지
1. JWT 토큰 저장
- JWT토큰을 WebView에 요청 헤더를 포함 시키기 위해 WebViewClient를 커스터 마이즈한다.
class CustomWebViewClient(private val context: Context) : WebViewClient() {
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
val jwtToken = getJwtToken(context)
val modifiedRequest = request?.let {
val headers = HashMap(it.requestHeaders)
jwtToken?.let { token ->
headers["Authorization"] = "Bearer $token"
}
it.newBuilder().apply {
headers(headers)
}.build()
}
return super.shouldInterceptRequest(view, modifiedRequest)
}
}
2. JWT 토큰을 쿠키로 저장하는 방법
- cookieManager를 사용하여 JWT 토큰을 쿠키에 저장한다.
fun setCookie(context: Context, url: String, token: String) {
val cookieManager = CookieManager.getInstance()
cookieManager.setAcceptCookie(true)
cookieManager.setCookie(url, "Authorization=Bearer $token; Path=/")
cookieManager.flush()
}
- webView를 초기화하고, URL을 로드하기 전에 쿠키를 설정한다.
val webView = findViewById<WebView>(R.id.webView)
// 쿠키 설정
val url = "https://your-url.com"
val jwtToken = getJwtToken(this)
jwtToken?.let { token ->
setCookie(this, url, token)
}
// WebView 설정 및 URL 로드
webView.webViewClient = WebViewClient()
webView.loadUrl(url)