HOWTO¶
이 장에서는 몇가지 작은 팁들을 제공합니다.
기본적인 인증¶
사이트나 특정 액션에 Basic authentication 을 이용하여 보호할 수 있습니다.
Xitrum은 digest authentication 을 지원하지 않습니다 잘못된 보안 방법으로 인해 man-in-the-middle attack에 취약하므로 보다 나은 방법으로서 Xitrum을 이용하여 HTTPS를 사용하는 것을 권장합니다. (Apache나 Nginx와 같은 리버스 프록시를 따로 구축할 필요가 없습니다)
전체 프로젝트에 기본적인 인증을 설정하는 방법¶
config/xitrum.conf
내부에 설정:
"basicAuth": {
"realm": "xitrum",
"username": "xitrum",
"password": "xitrum"
}
특정 액션에 기본 인증을 추가¶
import xitrum.Action
class MyAction extends Action {
beforeFilter {
basicAuth("Realm") { (username, password) =>
username == "username" && password == "password"
}
}
}
설정파일 로드¶
JSON 파일¶
JSON은 중첩된 구조를 설명하기에 알맞습니다.
config
디렉토리에 설정 파일을 저장합니다.
이 디렉토리는, 개발 모드에서 build.sbt에 의해, 프로덕션 모드에서는 script/runner
(또는 script/runner.bat
) 에 의해 자동적으로 클래스 패스에 포함됩니다.
myconfig.json:
{
"username": "God",
"password": "Does God need a password?",
"children": ["Adam", "Eva"]
}
로드방법:
import xitrum.util.Loader
case class MyConfig(username: String, password: String, children: Seq[String])
val myConfig = Loader.jsonFromClasspath[MyConfig]("myconfig.json")
주의:
- 키와 스트링은 큰따옴표로 둘러싸여 있어야 합니다.
- 현재는 JSON파일에 주석을 달 수 없습니다.
설정 파일¶
설정 파일을 사용할 수도 있습니다만 설정 파일은 안전하지 않고 UTF-8을 지원하지 않을뿐더러 중첩된 구조도 지원하지 않으므로 JSON을 사용하는 것이 훨씬 좋습니다.
myconfig.properties:
username = God
password = Does God need a password?
children = Adam, Eva
로드 방법:
import xitrum.util.Loader
// Here you get an instance of java.util.Properties
val properties = Loader.propertiesFromClasspath("myconfig.properties")
Typesafe한 설정파일¶
Xitrum은 Akka를 포함하고 있습니다. Akka는 Typesafe 사의 config library 라고 하는 라이브러리를 포함하고 있으며 더 나은 설정 방법을 제시합니다.
myconfig.conf:
username = God
password = Does God need a password?
children = ["Adam", "Eva"]
로드 방법:
import com.typesafe.config.{Config, ConfigFactory}
val config = ConfigFactory.load("myconfig.conf")
val username = config.getString("username")
val password = config.getString("password")
val children = config.getStringList("children")
직렬화 및 역직렬화¶
Array[Byte]
를 직렬화:
import xitrum.util.SeriDeseri
val bytes = SeriDeseri.toBytes("my serializable object")
다시 역직렬화:
val option = SeriDeseri.fromBytes[MyType](bytes) // Option[MyType]
파일에 저장 시:
import xitrum.util.Loader
Loader.bytesToFile(bytes, "myObject.bin")
파일에서 로드 시:
val bytes = Loader.bytesFromFile("myObject.bin")
데이터 암호화¶
다시 해독할 필요가 없는 데이터일 경우에는 MD5등을 사용할 수 있습니다.(단방향 암호화) 다시 해독할 필요가 있는 데이터일 경우에는 Xitrum에서 제공하는 라이브러리를 사용하면 됩니다.
import xitrum.util.Secure
// Array[Byte]
val encrypted = Secure.encrypt("my data".getBytes)
// Option[Array[Byte]]
val decrypted = Secure.decrypt(encrypted)
xitrum.util.UrlSafeBase64
을 이용하여 바이너리 데이터(HTML을 이용한 응답 등을 포함)를 일반적인 스트링값으로 암복호화가 가능합니다.
// cookie와 같이 URL내에 포함된 스트링
val string = UrlSafeBase64.noPaddingEncode(encrypted)
// Option[Array[Byte]]
val encrypted2 = UrlSafeBase64.autoPaddingDecode(string)
두 가지를 한 번에 결합할 수 있습니다:
import xitrum.util.SeriDeseri
val mySerializableObject = new MySerializableClass
// String
val encrypted = SeriDeseri.toSecureUrlSafeBase64(mySerializableObject)
// Option[MySerializableClass]
val decrypted = SeriDeseri.fromSecureUrlSafeBase64[MySerializableClass](encrypted)
SeriDeseri
는 Twitter Chill 를 사용하여 직렬화 및 역직렬화를 합니다.
데이터는 반드시 직렬화가 가능 해야 합니다.
특정한 키를 암호화:
val encrypted = Secure.encrypt("my data".getBytes, "my key")
val decrypted = Secure.decrypt(encrypted, "my key")
val encrypted = SeriDeseri.toSecureUrlSafeBase64(mySerializableObject, "my key")
val decrypted = SeriDeseri.fromSecureUrlSafeBase64[MySerializableClass](encrypted, "my key")
키가 지정되어 있지 않은 경우에는 config/xitrum.conf
파일 내의 secureKey
가 사용됩니다.
동일한 도매인 내의 여러 사이트¶
Nginx와 같은 리버스 프록시를 사용하여 같은 도메인 내의 여러 다른 사이트를 실행:
http://example.com/site1/...
http://example.com/site2/...
config/xitrum.conf
내의 baseUrl
을 정의합니다.
JavaScript코드 내에서 Ajax 요청에 정확한 URLs을 얻으려면 xitrum.js 내의 withBaseUrl
을 사용하면 됩니다.
# 만약 현재 사이트의 baseUrl이 "site1" 일 경우에 결과는:
# 다음과 같습니다. /site1/path/to/my/action
xitrum.withBaseUrl('/path/to/my/action')
Markdown 텍스트를 HTML로 변환¶
프로젝트가 이미 Scalate 을 사용하고 있다면 다음과 같이 해야 합니다:
import org.fusesource.scalamd.Markdown
val html = Markdown("input")
아니라면 라이브러리를 프로젝트의 build.sbt에 추가해야 합니다:
libraryDependencies += "org.fusesource.scalamd" %% "scalamd" % "1.6"
파일의 모니터링¶
파일이나 디렉토리의 StandardWatchEventKinds 에 콜백을 설정할 수 있습니다.
import java.nio.file.Paths
import xitrum.util.FileMonitor
val target = Paths.get("absolute_path_or_path_relative_to_application_directory").toAbsolutePath
FileMonitor.monitor(FileMonitor.MODIFY, target, { path =>
// Do some callback with path
println(s"File modified: $path")
// And stop monitoring if necessary
FileMonitor.unmonitor(FileMonitor.MODIFY, target)
})
FileMonitor
는 Schwatcher 를 사용하고 있습니다.
임시 디렉토리¶
기본적으로 Xitrum은 tmp
디렉토리 (xitrum.conf
의 tmpDir
에서 확인가능)를 생성된 scala파일의 저장이나 큰 업로드용 파일들을
저장하기 위해 사용합니다.
파일 경로 얻어오기:
xitrum.Config.xitrum.tmpDir.getAbsolutePath
파일이나 디렉토리 생성:
val file = new java.io.File(xitrum.Config.xitrum.tmpDir, "myfile")
val dir = new java.io.File(xitrum.Config.xitrum.tmpDir, "mydir")
dir.mkdirs()
비디오 스트리밍¶
다양한 비디오 스트리밍 방법 중 쉬운 방법은:
- .mp4 비디오 파일들에 간격을 주어서 플래이하는 동안 다운로드를 합니다.
- 그리고 Xitrum이 지원하는 HTTP서버와 같이 range requests 사용자는 다운로드 받지 않은 부분에 대하여 건너뛰기가 가능합니다.
MP4Box 를 이용하는 것으로 500 밀리초마다 데이터를 넣을 수 있습니다.
MP4Box -inter 500 movie.mp4