For authorization it's easiest to use the built-in UserSession which makes use of FormsAuthentication. Having the WebSharper.Web namespace open you can access the current request's context with Remoting.GetContext(). This is only accessible on the current thread so be sure to not call it in an async block as that is not guaranteed to run on the same thread:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
let withUserSession k =
    let ctx = Remoting.GetContext()
    async {
        return! k ctx.UserSession
    }

let withUser k =
    withUserSession <| fun sess ->
        async {
            let! user = sess.GetLoggedInUser ()
            return! k user
        }

let CheckCredentials uname pw = 
    // check credentials in db
    async.Return <| Some "user"

[<Rpc>]
let Login uname pw = 
    withUserSession <| fun sess ->
        async {
            let! user = CheckCredentials uname pw
            match user with
            | Some u -> do! sess.LoginUser u
            | None -> ()
        }

[<Rpc>]
let DoSomeUserStuff () =
    withUser <| fun user ->
        async {
            //...
            return 42
        }

If you want to directly access the http context and do some modifications by hand you can do something like:

1
2
3
4
5
6
7
8
9
10
11
12
let withContext k =
    let ctx = Remoting.GetContext ()
    let httpctx = ctx.Environment.["HttpContext"] :?> System.Web.HttpContextWrapper
    async {
        return! k httpctx
    }

[<Rpc>]
let DoSomething (input : string) =
    withContext <| fun ctx ->
        ctx.Response.StatusCode <- 404
        async.Return ""

but it's probably better not to modify status codes and the internals of the context when using Rpc. I'd much rather use a Result<'T> type to model success and failure and return that. I.e.:

1
2
3
4
5
6
7
type Error =
    | Unauhorized
    | Other of string

type Result<'T> =
    | Success of 'T
    | Failure of Error
By on 12/7/2015 1:57 AM ()

Hi Istvan, thanks for the detailed answer. In my case I am using a Owin self host and the sitelet will sit behind a jwt auth middleware. Therefore in order for my rpc calls to pass the auth, it will need to have the jwt bearer token in the headers.

How can I modify the request headers of the rpcs from the client code to include the token?

By on 12/7/2015 5:29 AM ()

I have try to look for resources but can't find a good example on how to add a header on an RPC call.

What would be the easiest way to add a Authorization header in an RPC request?

By on 12/8/2015 2:49 PM ()

It is possible to do this, though it's currently outside the documentation indeed. AJAX Remoting is implemented by calling methods on WebSharper.Remoting.AjaxProvider, so you can wrap that object to set the headers that you need:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[<JavaScript>]
module Remoting =
    open WebSharper.JavaScript

    let private originalProvider = WebSharper.Remoting.AjaxProvider

    type XhrProvider (token: string) =
        member this.AddHeaders(headers) =
            JS.Set headers "Authorization" token
            headers
        interface WebSharper.Remoting.IAjaxProvider with
            member this.Async url headers data ok err =
                originalProvider.Async url (this.AddHeaders headers) data ok err
            member this.Sync url headers data =
                originalProvider.Sync url (this.AddHeaders headers) data

    /// After calling this method, all RPC calls will send the given token.
    let Install token =
        WebSharper.Remoting.AjaxProvider <- XhrProvider(token)
By on 12/9/2015 3:25 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper