Ecoer Logo
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS34.47%
Net Worth
1.384USD
STEEM
0.000STEEM
SBD
0.000SBD
Own SP
25.838SP

Detailed Balance

STEEM
balance
0.000STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
25.838SP
Delegated Out
0.000SP
Delegation In
0.000SP
Effective Power
25.838SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
0.000SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "42075.533755 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "0.000000 VESTS",
  "sbd_balance": "0.000 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

namebabelek
id375040
rank68,799
reputation654747096523
created2017-09-18T19:45:09
recovery_accountsteem
proxyNone
post_count55
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2018-03-17T14:01:48
last_root_post2018-03-17T14:01:48
last_vote_time2018-03-14T16:31:03
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power9,800
delayed_votes0
balance0.000 STEEM
savings_balance0.000 STEEM
sbd_balance0.000 SBD
savings_sbd_balance0.000 SBD
vesting_shares42075.533755 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares0.000000 VESTS
reward_vesting_balance0.000000 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn5837441208
to_withdraw5837441208
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update2017-12-29T13:31:12
minedNo
sbd_seconds3,339,198
sbd_last_interest_payment2021-04-02T18:56:18
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "id": 375040,
  "name": "babelek",
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5YG2e4bvsowZ8vDGZgV4faWMvyqBqAZvixZjqfopbaQHr4m3dn",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM6dDZ9fXt1ypFJPpzBPrdkahZQddtiJgvtsq6T8kBzZbrnRq3h3",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [
      [
        "busy.app",
        1
      ],
      [
        "utopian.app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM5k3yCExVHVZoceb85CiiE7zykhUnTsJSChcXC2F2rUNM8rTHpL",
        1
      ]
    ]
  },
  "memo_key": "STM7LD6HaCJDWL6QiJXZWtDaGQzbQzAteyBWs2dz7hViB8SZaEMhc",
  "json_metadata": "",
  "posting_json_metadata": "",
  "proxy": "",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_account_update": "2017-12-29T13:31:12",
  "created": "2017-09-18T19:45:09",
  "mined": false,
  "recovery_account": "steem",
  "last_account_recovery": "1970-01-01T00:00:00",
  "reset_account": "null",
  "comment_count": 0,
  "lifetime_vote_count": 0,
  "post_count": 55,
  "can_vote": true,
  "voting_manabar": {
    "current_mana": 9800,
    "last_update_time": 1521045063
  },
  "downvote_manabar": {
    "current_mana": 0,
    "last_update_time": 1505763909
  },
  "voting_power": 9800,
  "balance": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "sbd_balance": "0.000 SBD",
  "sbd_seconds": "3339198",
  "sbd_seconds_last_update": "2021-04-02T18:59:45",
  "sbd_last_interest_payment": "2021-04-02T18:56:18",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "vesting_shares": "42075.533755 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "0.000000 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "withdrawn": "5837441208",
  "to_withdraw": "5837441208",
  "withdraw_routes": 0,
  "curation_rewards": 58,
  "posting_rewards": 45700,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "witnesses_voted_for": 0,
  "last_post": "2018-03-17T14:01:48",
  "last_root_post": "2018-03-17T14:01:48",
  "last_vote_time": "2018-03-14T16:31:03",
  "post_bandwidth": 0,
  "pending_claimed_accounts": 0,
  "vesting_balance": "0.000 STEEM",
  "reputation": "654747096523",
  "transfer_history": [],
  "market_history": [],
  "post_history": [],
  "vote_history": [],
  "other_history": [],
  "witness_votes": [],
  "tags_usage": [],
  "guest_bloggers": [],
  "rank": 68799
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
dat1replied to @babelek / r8y2cl
2022/03/18 14:17:09
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authordat1
permlinkr8y2cl
title
bodysir, how do i get the facebook token to input the API
json metadata{"app":"steemit/0.2"}
Transaction InfoBlock #62530540/Trx 62241b18ac9fba6b8624ee40e6b0285d364e6c3e
View Raw JSON Data
{
  "trx_id": "62241b18ac9fba6b8624ee40e6b0285d364e6c3e",
  "block": 62530540,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2022-03-18T14:17:09",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "dat1",
      "permlink": "r8y2cl",
      "title": "",
      "body": "sir, how do i get the facebook token to input the API",
      "json_metadata": "{\"app\":\"steemit/0.2\"}"
    }
  ]
}
2021/08/31 16:25:00
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authoribuzzing
permlinkqypplo
title
bodyCheers! https://www.linkedin.com/pulse/why-cant-i-react-facebook-deepak-gupta/ https://www.merchantcircle.com/blogs/iblog-alfred-ny/2021/8/Heres-What-You-Need-To-Know-About-Facebook-Dating/2067841 https://www.vingle.net/posts/3923955 https://ed.ted.com/on/QJJ3cQKX#digdeeper https://ed.ted.com/on/dLR2jL0d#digdeeper https://www.open.edu/openlearncreate/mod/oublog/viewpost.php?post=2872 https://mytrendingstories.com/den-mark/how-to-find-out-if-you-have-been-tagged-on-facebook-tqrtuw https://www.eudaimedia.com/?p=8115 https://murmur.csail.mit.edu/thread?group_name=iNews&tid=38231 https://writer.zohopublic.com/writer/published/dhko6ba4b11d7c47241bfab73939701228ba6 https://writer.zohopublic.com/writer/published/dhko6c89da48926154d7688f19d8c07c22028 https://lms.eonreality.com/eportfolios/12/Technology/How_To_Change_The_Language_On_Facebook https://techunwrapped.com/how-to-find-out-if-someone-has-unfollowed-you-on-facebook/ https://androidcure.com/how-to-change-your-facebook-password/ https://www.sbnation.com/users/Facebook%20Login%20Guide
json metadata{"links":["https://www.linkedin.com/pulse/why-cant-i-react-facebook-deepak-gupta/","https://www.merchantcircle.com/blogs/iblog-alfred-ny/2021/8/Heres-What-You-Need-To-Know-About-Facebook-Dating/2067841","https://www.vingle.net/posts/3923955","https://ed.ted.com/on/QJJ3cQKX#digdeeper","https://ed.ted.com/on/dLR2jL0d#digdeeper","https://www.open.edu/openlearncreate/mod/oublog/viewpost.php?post=2872","https://mytrendingstories.com/den-mark/how-to-find-out-if-you-have-been-tagged-on-facebook-tqrtuw","https://www.eudaimedia.com/?p=8115","https://murmur.csail.mit.edu/thread?group_name=iNews&tid=38231","https://writer.zohopublic.com/writer/published/dhko6ba4b11d7c47241bfab73939701228ba6","https://writer.zohopublic.com/writer/published/dhko6c89da48926154d7688f19d8c07c22028","https://lms.eonreality.com/eportfolios/12/Technology/How_To_Change_The_Language_On_Facebook","https://techunwrapped.com/how-to-find-out-if-someone-has-unfollowed-you-on-facebook/","https://androidcure.com/how-to-change-your-facebook-password/","https://www.sbnation.com/users/Facebook%20Login%20Guide"],"app":"steemit/0.2"}
Transaction InfoBlock #56849163/Trx 9e7912c6046b1299f6a24cbc55731c916938e29f
View Raw JSON Data
{
  "trx_id": "9e7912c6046b1299f6a24cbc55731c916938e29f",
  "block": 56849163,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2021-08-31T16:25:00",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "ibuzzing",
      "permlink": "qypplo",
      "title": "",
      "body": "Cheers!\nhttps://www.linkedin.com/pulse/why-cant-i-react-facebook-deepak-gupta/\nhttps://www.merchantcircle.com/blogs/iblog-alfred-ny/2021/8/Heres-What-You-Need-To-Know-About-Facebook-Dating/2067841\nhttps://www.vingle.net/posts/3923955\nhttps://ed.ted.com/on/QJJ3cQKX#digdeeper\nhttps://ed.ted.com/on/dLR2jL0d#digdeeper\nhttps://www.open.edu/openlearncreate/mod/oublog/viewpost.php?post=2872\nhttps://mytrendingstories.com/den-mark/how-to-find-out-if-you-have-been-tagged-on-facebook-tqrtuw\nhttps://www.eudaimedia.com/?p=8115\nhttps://murmur.csail.mit.edu/thread?group_name=iNews&tid=38231\nhttps://writer.zohopublic.com/writer/published/dhko6ba4b11d7c47241bfab73939701228ba6\nhttps://writer.zohopublic.com/writer/published/dhko6c89da48926154d7688f19d8c07c22028\nhttps://lms.eonreality.com/eportfolios/12/Technology/How_To_Change_The_Language_On_Facebook\nhttps://techunwrapped.com/how-to-find-out-if-someone-has-unfollowed-you-on-facebook/\nhttps://androidcure.com/how-to-change-your-facebook-password/\nhttps://www.sbnation.com/users/Facebook%20Login%20Guide",
      "json_metadata": "{\"links\":[\"https://www.linkedin.com/pulse/why-cant-i-react-facebook-deepak-gupta/\",\"https://www.merchantcircle.com/blogs/iblog-alfred-ny/2021/8/Heres-What-You-Need-To-Know-About-Facebook-Dating/2067841\",\"https://www.vingle.net/posts/3923955\",\"https://ed.ted.com/on/QJJ3cQKX#digdeeper\",\"https://ed.ted.com/on/dLR2jL0d#digdeeper\",\"https://www.open.edu/openlearncreate/mod/oublog/viewpost.php?post=2872\",\"https://mytrendingstories.com/den-mark/how-to-find-out-if-you-have-been-tagged-on-facebook-tqrtuw\",\"https://www.eudaimedia.com/?p=8115\",\"https://murmur.csail.mit.edu/thread?group_name=iNews&tid=38231\",\"https://writer.zohopublic.com/writer/published/dhko6ba4b11d7c47241bfab73939701228ba6\",\"https://writer.zohopublic.com/writer/published/dhko6c89da48926154d7688f19d8c07c22028\",\"https://lms.eonreality.com/eportfolios/12/Technology/How_To_Change_The_Language_On_Facebook\",\"https://techunwrapped.com/how-to-find-out-if-someone-has-unfollowed-you-on-facebook/\",\"https://androidcure.com/how-to-change-your-facebook-password/\",\"https://www.sbnation.com/users/Facebook%20Login%20Guide\"],\"app\":\"steemit/0.2\"}"
    }
  ]
}
babeleksent 16.226 SBD to @bittrex- "e848f4d3e52e46c0bcd"
2021/04/02 18:59:45
frombabelek
tobittrex
amount16.226 SBD
memoe848f4d3e52e46c0bcd
Transaction InfoBlock #52545138/Trx eda6cb352491b058aa608aa740e72f2b30740c2a
View Raw JSON Data
{
  "trx_id": "eda6cb352491b058aa608aa740e72f2b30740c2a",
  "block": 52545138,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2021-04-02T18:59:45",
  "op": [
    "transfer",
    {
      "from": "babelek",
      "to": "bittrex",
      "amount": "16.226 SBD",
      "memo": "e848f4d3e52e46c0bcd"
    }
  ]
}
babelekbought 1.754 STEEM for 0.192 SBD from @babelek
2021/04/02 18:58:00
current ownerworshipday
current orderid1617389873
current pays0.192 SBD
open ownerbabelek
open orderid1617389878
open pays1.754 STEEM
Transaction InfoBlock #52545103/Trx 0506eedb25d590e9241c506a790c4314c85708ec
View Raw JSON Data
{
  "trx_id": "0506eedb25d590e9241c506a790c4314c85708ec",
  "block": 52545103,
  "trx_in_block": 4,
  "op_in_trx": 0,
  "virtual_op": 1,
  "timestamp": "2021-04-02T18:58:00",
  "op": [
    "fill_order",
    {
      "current_owner": "worshipday",
      "current_orderid": 1617389873,
      "current_pays": "0.192 SBD",
      "open_owner": "babelek",
      "open_orderid": 1617389878,
      "open_pays": "1.754 STEEM"
    }
  ]
}
babelekblockchain operation: limit order create
2021/04/02 18:57:57
ownerbabelek
orderid1617389878
amount to sell1.754 STEEM
min to receive0.192 SBD
fill or killfalse
expiration2021-04-29T18:57:37
Transaction InfoBlock #52545102/Trx c970a568a391b92d71f67b3e0e66034a2746f6a7
View Raw JSON Data
{
  "trx_id": "c970a568a391b92d71f67b3e0e66034a2746f6a7",
  "block": 52545102,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2021-04-02T18:57:57",
  "op": [
    "limit_order_create",
    {
      "owner": "babelek",
      "orderid": 1617389878,
      "amount_to_sell": "1.754 STEEM",
      "min_to_receive": "0.192 SBD",
      "fill_or_kill": false,
      "expiration": "2021-04-29T18:57:37"
    }
  ]
}
babeleksent 1.000 SBD to @bittrex- "e848f4d3e52e46c0bcd"
2021/04/02 18:56:18
frombabelek
tobittrex
amount1.000 SBD
memoe848f4d3e52e46c0bcd
Transaction InfoBlock #52545069/Trx 3158278427f253733814b172febe45c8e62ed873
View Raw JSON Data
{
  "trx_id": "3158278427f253733814b172febe45c8e62ed873",
  "block": 52545069,
  "trx_in_block": 3,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2021-04-02T18:56:18",
  "op": [
    "transfer",
    {
      "from": "babelek",
      "to": "bittrex",
      "amount": "1.000 SBD",
      "memo": "e848f4d3e52e46c0bcd"
    }
  ]
}
2019/12/08 08:55:48
parent authorbabelek
parent permlinkwelcome-steemit
authorziona
permlinkre-welcome-steemit
title
bodyWelcome to steemit
json metadata{}
Transaction InfoBlock #38853083/Trx d12b657871e6b897afeeaebc9c860eae8d21a338
View Raw JSON Data
{
  "trx_id": "d12b657871e6b897afeeaebc9c860eae8d21a338",
  "block": 38853083,
  "trx_in_block": 10,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-12-08T08:55:48",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "welcome-steemit",
      "author": "ziona",
      "permlink": "re-welcome-steemit",
      "title": "",
      "body": "Welcome to steemit",
      "json_metadata": "{}"
    }
  ]
}
2019/12/08 08:55:33
parent authorbabelek
parent permlinkwelcome-steemit
authorziona
permlinkre-welcome-steemit
title
bodyWelcome to steemit
json metadata{}
Transaction InfoBlock #38853078/Trx ee0f80acf2920f47c1c87730278ed625d53bcde9
View Raw JSON Data
{
  "trx_id": "ee0f80acf2920f47c1c87730278ed625d53bcde9",
  "block": 38853078,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-12-08T08:55:33",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "welcome-steemit",
      "author": "ziona",
      "permlink": "re-welcome-steemit",
      "title": "",
      "body": "Welcome to steemit",
      "json_metadata": "{}"
    }
  ]
}
2019/09/18 20:13:15
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authorsteemitboard
permlinksteemitboard-notify-babelek-20190918t201314000z
title
bodyCongratulations @babelek! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@babelek/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@babelek) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=babelek)_</sub> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
Transaction InfoBlock #36538401/Trx 24bffa4f40904205ddaa1d8b0b76e61f5ab737c6
View Raw JSON Data
{
  "trx_id": "24bffa4f40904205ddaa1d8b0b76e61f5ab737c6",
  "block": 36538401,
  "trx_in_block": 4,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-09-18T20:13:15",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-babelek-20190918t201314000z",
      "title": "",
      "body": "Congratulations @babelek! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@babelek/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@babelek) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=babelek)_</sub>\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}"
    }
  ]
}
2018/10/15 10:47:09
parent authorbabelek
parent permlinkwelcome-steemit
authordany-dror
permlinkre-welcome-steemit
title
bodyWellcome to the community!
json metadata{}
Transaction InfoBlock #26827133/Trx ba7b2f5dcd53131bb9dae31b063e0623b07854fc
View Raw JSON Data
{
  "trx_id": "ba7b2f5dcd53131bb9dae31b063e0623b07854fc",
  "block": 26827133,
  "trx_in_block": 23,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-10-15T10:47:09",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "welcome-steemit",
      "author": "dany-dror",
      "permlink": "re-welcome-steemit",
      "title": "",
      "body": "Wellcome to the community!",
      "json_metadata": "{}"
    }
  ]
}
2018/10/15 10:46:36
parent authorbabelek
parent permlinkwelcome-steemit
authordany-dror
permlinkre-welcome-steemit
title
bodyWellcome to the community!
json metadata{}
Transaction InfoBlock #26827122/Trx 07ba3e5493cc7ff673889d4c35352ac972370c20
View Raw JSON Data
{
  "trx_id": "07ba3e5493cc7ff673889d4c35352ac972370c20",
  "block": 26827122,
  "trx_in_block": 17,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-10-15T10:46:36",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "welcome-steemit",
      "author": "dany-dror",
      "permlink": "re-welcome-steemit",
      "title": "",
      "body": "Wellcome to the community!",
      "json_metadata": "{}"
    }
  ]
}
2018/09/19 00:06:33
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authorsteemitboard
permlinksteemitboard-notify-babelek-20180919t000632000z
title
bodyCongratulations @babelek! You have received a personal award! [![](https://steemitimages.com/70x70/http://steemitboard.com/@babelek/birthday1.png)](http://steemitboard.com/@babelek) 1 Year on Steemit <sub>_Click on the badge to view your Board of Honor._</sub> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
Transaction InfoBlock #26066253/Trx 3216f8897b8a475dbfa8e75936518c1596189cc8
View Raw JSON Data
{
  "trx_id": "3216f8897b8a475dbfa8e75936518c1596189cc8",
  "block": 26066253,
  "trx_in_block": 3,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-09-19T00:06:33",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-babelek-20180919t000632000z",
      "title": "",
      "body": "Congratulations @babelek! You have received a personal award!\n\n[![](https://steemitimages.com/70x70/http://steemitboard.com/@babelek/birthday1.png)](http://steemitboard.com/@babelek)  1 Year on Steemit\n<sub>_Click on the badge to view your Board of Honor._</sub>\n\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}"
    }
  ]
}
2018/05/31 21:45:21
voterbbcbreaking
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #22923167/Trx f83f284b5d7a369bea83bd2dcdf7206b708cdd33
View Raw JSON Data
{
  "trx_id": "f83f284b5d7a369bea83bd2dcdf7206b708cdd33",
  "block": 22923167,
  "trx_in_block": 38,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-31T21:45:21",
  "op": [
    "vote",
    {
      "voter": "bbcbreaking",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
steemdelegated 0.000 SP to @babelek
2018/04/29 22:37:12
delegatorsteem
delegateebabelek
vesting shares0.000000 VESTS
Transaction InfoBlock #22003145/Trx 1020ce675a0de3058342c7eec18b4fb61134a859
View Raw JSON Data
{
  "trx_id": "1020ce675a0de3058342c7eec18b4fb61134a859",
  "block": 22003145,
  "trx_in_block": 29,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T22:37:12",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "babelek",
      "vesting_shares": "0.000000 VESTS"
    }
  ]
}
babelekclaimed reward balance: 17.031 SBD, 10.471 SP
2018/04/29 21:21:12
accountbabelek
reward steem0.000 STEEM
reward sbd17.031 SBD
reward vests17050.588581 VESTS
Transaction InfoBlock #22001625/Trx 26ccb18110adc25eefe2c16bdeeaa07676d4c536
View Raw JSON Data
{
  "trx_id": "26ccb18110adc25eefe2c16bdeeaa07676d4c536",
  "block": 22001625,
  "trx_in_block": 34,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-29T21:21:12",
  "op": [
    "claim_reward_balance",
    {
      "account": "babelek",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "17.031 SBD",
      "reward_vests": "17050.588581 VESTS"
    }
  ]
}
resteembosssent 0.001 STEEM to @babelek- "★★★ Hi! Wishes success in your creativity on Steemit! If your post hasn't been noticed , @resteemboss can help you. Send 1.5 SBD or STEEM to @resteemboss or to any of 4 services, and we will make rest..."
2018/04/11 21:57:24
fromresteemboss
tobabelek
amount0.001 STEEM
memo★★★ Hi! Wishes success in your creativity on Steemit! If your post hasn't been noticed , @resteemboss can help you. Send 1.5 SBD or STEEM to @resteemboss or to any of 4 services, and we will make resteem to 50.000+ followers, guarantee + 45 upvote , your post will be surely noticed . RESTEEM BOT 4 in 1 . @bigshot + @hotlist + @re-blog + @artcity . Service Active ★★★
Transaction InfoBlock #21484687/Trx b760855fbaf66e20ddfd928dad86064a479e63eb
View Raw JSON Data
{
  "trx_id": "b760855fbaf66e20ddfd928dad86064a479e63eb",
  "block": 21484687,
  "trx_in_block": 5,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-11T21:57:24",
  "op": [
    "transfer",
    {
      "from": "resteemboss",
      "to": "babelek",
      "amount": "0.001 STEEM",
      "memo": "★★★ Hi! Wishes success in your creativity on Steemit! If your post hasn't been noticed , @resteemboss can help you. Send 1.5 SBD or STEEM to @resteemboss or to any of 4 services, and we will make resteem to 50.000+ followers, guarantee + 45 upvote , your post will be surely noticed . RESTEEM BOT 4 in 1 . @bigshot + @hotlist + @re-blog + @artcity . Service Active ★★★"
    }
  ]
}
bigshotsent 0.001 STEEM to @babelek- "Hi , my friend ! Do you want that your post was noticed ? Resteem to 13.000+ Follower , Upvote 100% , min 20 Upvote . Send 0.6 SBD or STEEM to @bigshot ( URL in the Memo ) . Service Active"
2018/04/02 20:20:00
frombigshot
tobabelek
amount0.001 STEEM
memoHi , my friend ! Do you want that your post was noticed ? Resteem to 13.000+ Follower , Upvote 100% , min 20 Upvote . Send 0.6 SBD or STEEM to @bigshot ( URL in the Memo ) . Service Active
Transaction InfoBlock #21223567/Trx bd12283f848f30d03dd4ceefe76347c411dfdd36
View Raw JSON Data
{
  "trx_id": "bd12283f848f30d03dd4ceefe76347c411dfdd36",
  "block": 21223567,
  "trx_in_block": 33,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-04-02T20:20:00",
  "op": [
    "transfer",
    {
      "from": "bigshot",
      "to": "babelek",
      "amount": "0.001 STEEM",
      "memo": "Hi , my friend ! Do you want that your post was noticed ? Resteem to 13.000+ Follower , Upvote 100% , min 20 Upvote . Send 0.6 SBD or STEEM to @bigshot ( URL in the Memo ) . Service Active"
    }
  ]
}
babelekreceived 17.031 SBD, 10.468 SP author reward for @babelek / how-to-create-facebook-login-in-asp-net-core-web-api
2018/03/24 14:01:48
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
sbd payout17.031 SBD
steem payout0.000 STEEM
vesting payout17046.505404 VESTS
Transaction InfoBlock #20956883/Virtual Operation #15
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20956883,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 15,
  "timestamp": "2018-03-24T14:01:48",
  "op": [
    "author_reward",
    {
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "sbd_payout": "17.031 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "17046.505404 VESTS"
    }
  ]
}
utopian.payreceived 6.978 SP benefactor reward from @babelek
2018/03/24 14:01:48
benefactorutopian.pay
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout11363.656762 VESTS
Transaction InfoBlock #20956883/Virtual Operation #14
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20956883,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 14,
  "timestamp": "2018-03-24T14:01:48",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "11363.656762 VESTS"
    }
  ]
}
haveaheartsent 0.001 SBD to @babelek- "Hello. Tomorrow is my wife's birthday. If you have the time, we would appreciate it if you could read this. https://steemit.com/love/@crystalhuman/please-help-me-keep-her Thank you."
2018/03/22 03:56:00
fromhaveaheart
tobabelek
amount0.001 SBD
memoHello. Tomorrow is my wife's birthday. If you have the time, we would appreciate it if you could read this. https://steemit.com/love/@crystalhuman/please-help-me-keep-her Thank you.
Transaction InfoBlock #20887528/Trx 0fca27007620208fe4a526263ff905dc20e6b080
View Raw JSON Data
{
  "trx_id": "0fca27007620208fe4a526263ff905dc20e6b080",
  "block": 20887528,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-22T03:56:00",
  "op": [
    "transfer",
    {
      "from": "haveaheart",
      "to": "babelek",
      "amount": "0.001 SBD",
      "memo": "Hello. Tomorrow is my wife's birthday. If you have the time, we would appreciate it if you could read this. https://steemit.com/love/@crystalhuman/please-help-me-keep-her Thank you."
    }
  ]
}
2018/03/20 16:19:39
voterebenzy
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20845239/Trx 59d323f942d92a52d739e41ba33c2fb51a57fe3b
View Raw JSON Data
{
  "trx_id": "59d323f942d92a52d739e41ba33c2fb51a57fe3b",
  "block": 20845239,
  "trx_in_block": 48,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-20T16:19:39",
  "op": [
    "vote",
    {
      "voter": "ebenzy",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/20 15:45:30
voteriqbaladan
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20844559/Trx b0b043de374e7010fe1506de54de205a0cae95ee
View Raw JSON Data
{
  "trx_id": "b0b043de374e7010fe1506de54de205a0cae95ee",
  "block": 20844559,
  "trx_in_block": 41,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-20T15:45:30",
  "op": [
    "vote",
    {
      "voter": "iqbaladan",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/20 08:32:27
voterjustgeorge
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20835919/Trx 56d605b4e7c4d883a296ca53b5dd2536fb4d4720
View Raw JSON Data
{
  "trx_id": "56d605b4e7c4d883a296ca53b5dd2536fb4d4720",
  "block": 20835919,
  "trx_in_block": 8,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-20T08:32:27",
  "op": [
    "vote",
    {
      "voter": "justgeorge",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/20 08:22:48
voterantonella
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20835726/Trx 889be65a42517a229255e0adbae5f4f0935d573e
View Raw JSON Data
{
  "trx_id": "889be65a42517a229255e0adbae5f4f0935d573e",
  "block": 20835726,
  "trx_in_block": 69,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-20T08:22:48",
  "op": [
    "vote",
    {
      "voter": "antonella",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/20 06:25:57
votergiftsideas
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20833394/Trx 1e9747c542c54696bf86dd527e80fb52f13f59c8
View Raw JSON Data
{
  "trx_id": "1e9747c542c54696bf86dd527e80fb52f13f59c8",
  "block": 20833394,
  "trx_in_block": 27,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-20T06:25:57",
  "op": [
    "vote",
    {
      "voter": "giftsideas",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/19 18:47:51
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authorutopian-io
permlinkre-babelek-how-to-create-facebook-login-in-asp-net-core-web-api-20180319t184752375z
title
body### Hey @babelek I am @utopian-io. I have just upvoted you! #### Achievements - You have less than 500 followers. Just gave you a gift to help you succeed! - Seems like you contribute quite often. AMAZING! #### Community-Driven Witness! I am the first and only Steem Community-Driven Witness. <a href="https://discord.gg/zTrEMqB">Participate on Discord</a>. Lets GROW TOGETHER! - <a href="https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1">Vote for my Witness With SteemConnect</a> - <a href="https://v2.steemconnect.com/sign/account-witness-proxy?proxy=utopian-io&approve=1">Proxy vote to Utopian Witness with SteemConnect</a> - Or vote/proxy on <a href="https://steemit.com/~witnesses">Steemit Witnesses</a> [![mooncryption-utopian-witness-gif](https://steemitimages.com/DQmYPUuQRptAqNBCQRwQjKWAqWU3zJkL3RXVUtEKVury8up/mooncryption-s-utopian-io-witness-gif.gif)](https://steemit.com/~witnesses) **Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #20819443/Trx add8ebfdddc7fe16290baa515bb459cc6c245bb5
View Raw JSON Data
{
  "trx_id": "add8ebfdddc7fe16290baa515bb459cc6c245bb5",
  "block": 20819443,
  "trx_in_block": 79,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T18:47:51",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "utopian-io",
      "permlink": "re-babelek-how-to-create-facebook-login-in-asp-net-core-web-api-20180319t184752375z",
      "title": "",
      "body": "### Hey @babelek I am @utopian-io. I have just upvoted you!\n#### Achievements\n- You have less than 500 followers. Just gave you a gift to help you succeed!\n- Seems like you contribute quite often. AMAZING!\n#### Community-Driven Witness!\nI am the first and only Steem Community-Driven Witness. <a href=\"https://discord.gg/zTrEMqB\">Participate on Discord</a>. Lets GROW TOGETHER!\n- <a href=\"https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1\">Vote for my Witness With SteemConnect</a>\n- <a href=\"https://v2.steemconnect.com/sign/account-witness-proxy?proxy=utopian-io&approve=1\">Proxy vote to Utopian Witness with SteemConnect</a>\n- Or vote/proxy on <a href=\"https://steemit.com/~witnesses\">Steemit Witnesses</a>\n\n[![mooncryption-utopian-witness-gif](https://steemitimages.com/DQmYPUuQRptAqNBCQRwQjKWAqWU3zJkL3RXVUtEKVury8up/mooncryption-s-utopian-io-witness-gif.gif)](https://steemit.com/~witnesses)\n\n**Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/03/19 18:47:48
voterutopian-io
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight1092 (10.92%)
Transaction InfoBlock #20819442/Trx 61cfded2f487519b851cc242d57ca0dbae8109c4
View Raw JSON Data
{
  "trx_id": "61cfded2f487519b851cc242d57ca0dbae8109c4",
  "block": 20819442,
  "trx_in_block": 22,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T18:47:48",
  "op": [
    "vote",
    {
      "voter": "utopian-io",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 1092
    }
  ]
}
2018/03/19 18:25:39
voterjohnesan
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20818999/Trx acfd0bf41847947a06e66418fa7840e1367115fb
View Raw JSON Data
{
  "trx_id": "acfd0bf41847947a06e66418fa7840e1367115fb",
  "block": 20818999,
  "trx_in_block": 27,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T18:25:39",
  "op": [
    "vote",
    {
      "voter": "johnesan",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/19 17:48:12
votergutzygwin
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight2500 (25.00%)
Transaction InfoBlock #20818251/Trx ccc0dcd349e4335b58dd3919c05c4d17925c8d06
View Raw JSON Data
{
  "trx_id": "ccc0dcd349e4335b58dd3919c05c4d17925c8d06",
  "block": 20818251,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T17:48:12",
  "op": [
    "vote",
    {
      "voter": "gutzygwin",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 2500
    }
  ]
}
2018/03/19 16:56:57
voterazwarrangkuti
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight7500 (75.00%)
Transaction InfoBlock #20817226/Trx 2668f987bb2afa0b7140914364155af9ccd1051b
View Raw JSON Data
{
  "trx_id": "2668f987bb2afa0b7140914364155af9ccd1051b",
  "block": 20817226,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T16:56:57",
  "op": [
    "vote",
    {
      "voter": "azwarrangkuti",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 7500
    }
  ]
}
2018/03/19 14:52:48
votercifer
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight6500 (65.00%)
Transaction InfoBlock #20814743/Trx 4f4e9e582cbe57492597c74443b26c292cf7a7fb
View Raw JSON Data
{
  "trx_id": "4f4e9e582cbe57492597c74443b26c292cf7a7fb",
  "block": 20814743,
  "trx_in_block": 20,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T14:52:48",
  "op": [
    "vote",
    {
      "voter": "cifer",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 6500
    }
  ]
}
2018/03/19 14:51:54
parent authorbabelek
parent permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
authorcreon
permlinkre-babelek-how-to-create-facebook-login-in-asp-net-core-web-api-20180319t145149745z
title
bodyThank you for the contribution. It has been approved. You can contact us on [Discord](https://discord.gg/uTyJkNm). **[[utopian-moderator]](https://utopian.io/moderators)**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #20814725/Trx 8f53ec99d3f44ddc58699c354a198fca6dc249ee
View Raw JSON Data
{
  "trx_id": "8f53ec99d3f44ddc58699c354a198fca6dc249ee",
  "block": 20814725,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T14:51:54",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "author": "creon",
      "permlink": "re-babelek-how-to-create-facebook-login-in-asp-net-core-web-api-20180319t145149745z",
      "title": "",
      "body": "Thank you for the contribution. It has been approved.\n\nYou can contact us on [Discord](https://discord.gg/uTyJkNm).\n**[[utopian-moderator]](https://utopian.io/moderators)**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/03/19 14:51:36
parent author
parent permlinkutopian-io
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
titleHow to create facebook login in ASP.NET Core Web API
body #### What Will I Learn? - How to use Facebook API - How to create facebook login to your application - How to use JWT tokens #### Requirements - C# - ASP.NET Core - Visual Studio 2015+/ Visual Studio Code #### Difficulty - Intermediate #### Tutorial Contents In this tutorial I will present how to create logic for Facebook login, using ASP.NET Core Web API. I will show you how to make full service and REST communication with another part application witch can be mobile application or web application. At the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017. <center>![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg) </center> <center>![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg) </center> ### How will it work? When user click in the mobile application that he want to login by facebook, mobile application will send login request to facebook API, when credentials are correctly he will receive accessToken from facebook, this token is sending to our API where our API will send to facebook API request for identify user by accessToken. If everything will be ok facebook will return all information about particular user. Our service will create ours tokens and return this to mobile application. Since then mobile appplication will be using our access token for all request. In the new project I will create new folder with 4 classes. It will be Resource classes, in this classes we will define the models, witch we will be receiving or sending by REST. <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png) </center> I created 4 classes: - FacebookLoginresource - FacebookUserResource - TokenResource - AuthorizationTokenResource First and second class will be used for facebook login, next 2 classes will be used for authorization particular user in our application using JWT Tokens. FacebookLoginResource: ``` public class FacebookLoginResource { [Required] [StringLength(255)] public string facebookToken { get; set; } } ``` FacebookUserResource ``` public class FacebookUserResource { public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string Picture { get; set; } } ``` TokenResource ``` public class TokenResource { public string Token { get; set; } public long Expiry { get; set; } } ``` AuthorizationTokenResource ``` public class AuthorizationTokensResource { public TokenResource AccessToken { get; set; } public TokenResource RefreshToken { get; set; } } ``` Next step is creating a couple of services responsible for logic. I will create 3 service, one for communication with our mobile application, second for communication with facebook API, and third for creating JWT tokens. <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png) </center> AccountService ``` public class AccountService { private readonly FacebookService _facebookService; private readonly JwtHandler _jwtHandler; public AccountService(FacebookService facebookService, JwtHandler jwtHandler) { _facebookService = facebookService; _jwtHandler = jwtHandler; } public async Task<AuthorizationTokensResource> FacebookLoginAsync(FacebookLoginResource facebookLoginResource) { if (string.IsNullOrEmpty(facebookLoginResource.facebookToken)) { throw new Exception("Token is null or empty"); } var facebookUser = await _facebookService.GetUserFromFacebookAsync(facebookLoginResource.facebookToken); var domainUser = await unitOfWork.Users.GetAsync(facebookUser.Email); return await CreateAccessTokens(domainUser, facebookLoginResource.DeviceId, facebookLoginResource.DeviceName); } private async Task<AuthorizationTokensResource> CreateAccessTokens(User user, string deviceId, string deviceName) { var accessToken = _jwtHandler.CreateAccessToken(user.Id, user.Email, user.Role); var refreshToken = _jwtHandler.CreateRefreshToken(user.Id); return new AuthorizationTokensResource { AccessToken = accessToken, RefreshToken = refreshToken }; } } ``` FacebookService ``` public class FacebookService { private readonly HttpClient _httpClient; public FacebookService() { _httpClient = new HttpClient { BaseAddress = new Uri("https://graph.facebook.com/v2.8/") }; _httpClient.DefaultRequestHeaders .Accept .Add(new MediaTypeWithQualityHeaderValue("application/json")); } public async Task<FacebookUserResource> GetUserFromFacebookAsync(string facebookToken) { var result = await GetAsync<dynamic>(facebookToken, "me", "fields=first_name,last_name,email,picture.width(100).height(100)"); if (result == null) { throw new Exception("User from this token not exist"); } var account = new FacebookUserResource() { Email = result.email, FirstName = result.first_name, LastName = result.last_name, Picture = result.picture.data.url }; return account; } private async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null) { var response = await _httpClient.GetAsync($"{endpoint}?access_token={accessToken}&{args}"); if (!response.IsSuccessStatusCode) return default(T); var result = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<T>(result); } } ``` JwtHandler ``` public class JwtHandler { private readonly IConfiguration _configuration; public JwtHandler(IConfiguration configuration) { _configuration = configuration; } public TokenResource CreateAccessToken(Guid userId, string email, Role role) { var now = DateTime.UtcNow; var claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()), new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Role, role.ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64), }; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"])), SecurityAlgorithms.HmacSha256); var expiry = now.AddMinutes(double.Parse(_configuration["Tokens:AccessExpireMinutes"])); var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials); var token = new JwtSecurityTokenHandler().WriteToken(jwt); return CreateTokenResource(token, expiry.ToTimeStamp()); } public TokenResource CreateRefreshToken(Guid userId) { var now = DateTime.UtcNow; var claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64), }; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"])), SecurityAlgorithms.HmacSha256); var expiry = now.AddMinutes(double.Parse(_configuration["Tokens:RefreshExpireMinutes"])); var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials); var token = new JwtSecurityTokenHandler().WriteToken(jwt); return CreateTokenResource(token, expiry.ToTimeStamp()); } private JwtSecurityToken CreateSecurityToken(IEnumerable<Claim> claims, DateTime now, DateTime expiry, SigningCredentials credentials) => new JwtSecurityToken(claims: claims, notBefore: now, expires: expiry, signingCredentials: credentials); private static TokenResource CreateTokenResource(string token, long expiry) => new TokenResource { Token = token, Expiry = expiry }; } ``` AccountService has 2 methods: - FacebookLogin - CreateAccessTokens Facebook Login method is taking facebookLoginresource as parameter, then check is facebokToken is null, next step is checking if user with this accesstoken exist in facebook. If everything is ok createaccess token method is calling. FacebookService has also 2 methods: - GetUserFromFacebook - GetAsync<T> first method is taking accessToken as parameter and is using this token to check if is in facebook exist user connected with this token. If facebook return basic information about this user is creating a facebookUser resource witch is returning to access token. JWTService has method responsible for creating JwtTokens, more information about it you can find in my other tutorial: [JwtTokens](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api) Last part is creating a new Controller <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png) </center> ``` private readonly AccountService _accountService; public AccountController(AccountService accountService) { _accountService = accountService; } [HttpPost] [Route("account/login/facebook")] public async Task<IActionResult> FacebookLoginAsync([FromBody] FacebookLoginResource resource) { var authorizationTokens = await _accountService.FacebookLoginAsync(resource); return Ok(authorizationTokens); } ``` This controller has only one method for taking facebookLoginResource and returning a authorization tokens. #### Curriculum - [Saving image in database](https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0) - [Asp.Net Core with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core) - [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0) - [Manage Refresh token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api) - [Custom error handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@babelek/how-to-create-facebook-login-in-asp-net-core-web-api">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":17620347,"name":"Home","full_name":"aspnet/Home","html_url":"https://github.com/aspnet/Home","fork":false,"owner":{"login":"aspnet"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopina-io","tutorial","facebook"],"users":["babelek"],"links":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png","https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png","https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0","https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core","https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0","https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0"],"image":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png"],"moderator":{"account":"creon","time":"2018-03-19T14:51:35.026Z","reviewed":true,"pending":false,"flagged":false},"questions":[{"question":"Is the project description formal?","answers":[{"value":"Yes it’s straight to the point","selected":true,"score":10},{"value":"Need more description ","selected":false,"score":5},{"value":"Not too descriptive","selected":false,"score":0}],"selected":0},{"question":"Is the language / grammar correct?","answers":[{"value":"Yes","selected":true,"score":20},{"value":"A few mistakes","selected":false,"score":10},{"value":"It's pretty bad","selected":false,"score":0}],"selected":0},{"question":"Was the template followed?","answers":[{"value":"Yes","selected":true,"score":10},{"value":"Partially","selected":false,"score":5},{"value":"No","selected":false,"score":0}],"selected":0},{"question":"Is there information about the additional frameworks?","answers":[{"value":"Yes, everything is explained","selected":true,"score":5},{"value":"Yes, but not enough","selected":false,"score":3},{"value":"No details at all","selected":false,"score":0}],"selected":0},{"question":"Is there code in the tutorial?","answers":[{"value":"Yes, and it’s well explained","selected":true,"score":5},{"value":"Yes, but no explanation","selected":false,"score":3},{"value":"No","selected":false,"score":0}],"selected":0},{"question":"Is the tutorial explains technical aspects well enough?","answers":[{"value":"Yes, it teaches how and why about technical aspects","selected":true,"score":5},{"value":"Yes, but it’s not good/enough","selected":false,"score":3},{"value":"No, it explains poorly","selected":false,"score":0}],"selected":0},{"question":"Is the tutorial general and dense enough?","answers":[{"value":"Yes, it’s general and dense","selected":true,"score":5},{"value":"Kinda, it might be more generalized","selected":false,"score":3},{"value":"No, it’s sliced unnecessarily to keep part number high","selected":false,"score":0}],"selected":0},{"question":"Is there an outline for the tutorial content at the beginning of the post","answers":[{"value":"Yes, there is a well prepared outline in “What will I learn?” or another outline section","selected":true,"score":5},{"value":"Yes, but there is no proper listing for every step of the tutorial or it’s not detailed enough","selected":false,"score":3},{"value":"No, there is no outline for the steps.","selected":false,"score":0}],"selected":0},{"question":"Is the visual content of good quality?","answers":[{"value":"Yes","selected":false,"score":5},{"value":"Yes, but bad quality","selected":false,"score":3},{"value":"No","selected":true,"score":0}],"selected":2},{"question":"Is this a tutorial series?","answers":[{"value":"Yes","selected":false,"score":5},{"value":"Yes, but first part","selected":false,"score":3},{"value":"No","selected":true,"score":0}],"selected":2},{"question":"Is the tutorial post structured?","answers":[{"value":"Yes","selected":true,"score":5},{"value":"Not so good","selected":false,"score":3},{"value":"No","selected":false,"score":0}],"selected":0}],"score":49}
Transaction InfoBlock #20814719/Trx cfb7ea162014ec1fb24b978c05bfedc30f6999ac
View Raw JSON Data
{
  "trx_id": "cfb7ea162014ec1fb24b978c05bfedc30f6999ac",
  "block": 20814719,
  "trx_in_block": 27,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-19T14:51:36",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "title": "How to create facebook login in ASP.NET Core Web API",
      "body": "\n#### What Will I Learn?\n\n- How to use Facebook API\n- How to create facebook login to your application\n- How to use JWT tokens\n\n#### Requirements\n\n- C#\n- ASP.NET Core\n- Visual Studio 2015+/ Visual Studio Code\n\n#### Difficulty\n\n- Intermediate\n\n#### Tutorial Contents\nIn this tutorial I will present how to create logic for Facebook login, using ASP.NET Core Web API. I will show you how to make full service and REST communication with another part application witch can be mobile application or web application. \n\nAt the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017. \n<center>![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg)\n</center>\n\n<center>![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg)\n</center>\n\n### How will it work?\nWhen user click in the mobile application that he want to login by facebook, mobile application will send login request to facebook API,  when credentials are correctly he will receive accessToken from facebook, this token is sending to our API where our API will send to facebook API request for identify user by accessToken. If everything will be ok  facebook will return all information about particular user. Our service will create ours tokens and return this to mobile application. Since then mobile appplication will be using our access token for all request.\n\nIn the new project I will create new folder with 4 classes. It will be Resource classes, in this classes we will define the models, witch we will be receiving or sending by REST.\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png)\n</center>\n\nI created 4 classes:\n- FacebookLoginresource\n- FacebookUserResource\n- TokenResource\n- AuthorizationTokenResource\n\nFirst and second class will be used for facebook login, next 2 classes will be used for authorization particular user in our application using JWT Tokens.\n\nFacebookLoginResource: \n```\n    public class FacebookLoginResource\n    {\n        [Required]\n        [StringLength(255)]\n        public string facebookToken { get; set; }\n    }\n```\nFacebookUserResource\n```\n    public class FacebookUserResource\n    {\n        public string FirstName { get; set; }\n        public string LastName { get; set; }\n        public string Email { get; set; }\n        public string Picture { get; set; }\n    }\n```\n\nTokenResource\n```\n    public class TokenResource\n    {\n        public string Token { get; set; }\n        public long Expiry { get; set; }\n    }\n```\nAuthorizationTokenResource\n```\n    public class AuthorizationTokensResource\n    {\n        public TokenResource AccessToken { get; set; }\n        public TokenResource RefreshToken { get; set; }\n    }\n```\n\nNext step is creating a couple of services responsible for logic. I will create 3 service, one for communication with our mobile application, second for communication with facebook API, and third for creating JWT tokens.\n\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png)\n</center>\n\nAccountService\n```\n public class AccountService\n    {\n        private readonly FacebookService _facebookService;\n        private readonly JwtHandler _jwtHandler;\n\n        public AccountService(FacebookService facebookService, JwtHandler jwtHandler)\n        {\n            _facebookService = facebookService;\n            _jwtHandler = jwtHandler;\n        }\n\n        public async Task<AuthorizationTokensResource> FacebookLoginAsync(FacebookLoginResource facebookLoginResource)\n        {\n            if (string.IsNullOrEmpty(facebookLoginResource.facebookToken))\n            {\n                throw new Exception(\"Token is null or empty\");\n            }\n\n            var facebookUser = await _facebookService.GetUserFromFacebookAsync(facebookLoginResource.facebookToken);\n            var domainUser = await unitOfWork.Users.GetAsync(facebookUser.Email);\n\n            return await CreateAccessTokens(domainUser, facebookLoginResource.DeviceId,\n                facebookLoginResource.DeviceName);\n        }\n\n        private async Task<AuthorizationTokensResource> CreateAccessTokens(User user, string deviceId,\n            string deviceName)\n        {\n            var accessToken = _jwtHandler.CreateAccessToken(user.Id, user.Email, user.Role);\n            var refreshToken = _jwtHandler.CreateRefreshToken(user.Id);\n\n            return new AuthorizationTokensResource { AccessToken = accessToken, RefreshToken = refreshToken };\n        }\n    }\n```\n\nFacebookService\n```\n    public class FacebookService\n    {\n        private readonly HttpClient _httpClient;\n\n        public FacebookService()\n        {\n            _httpClient = new HttpClient\n            {\n                BaseAddress = new Uri(\"https://graph.facebook.com/v2.8/\")\n            };\n            _httpClient.DefaultRequestHeaders\n                .Accept\n                .Add(new MediaTypeWithQualityHeaderValue(\"application/json\"));\n        }\n\n\n        public async Task<FacebookUserResource> GetUserFromFacebookAsync(string facebookToken)\n        {\n            var result = await GetAsync<dynamic>(facebookToken, \"me\", \"fields=first_name,last_name,email,picture.width(100).height(100)\");\n            if (result == null)\n            {\n                throw new Exception(\"User from this token not exist\");\n            }\n\n            var account = new FacebookUserResource()\n            {\n                Email = result.email,\n                FirstName = result.first_name,\n                LastName = result.last_name,\n                Picture = result.picture.data.url\n            };\n\n            return account;\n        }\n\n        private async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null)\n        {\n            var response = await _httpClient.GetAsync($\"{endpoint}?access_token={accessToken}&{args}\");\n            if (!response.IsSuccessStatusCode)\n                return default(T);\n\n            var result = await response.Content.ReadAsStringAsync();\n\n            return JsonConvert.DeserializeObject<T>(result);\n        }\n    }\n```\nJwtHandler\n```\npublic class JwtHandler\n    {\n        private readonly IConfiguration _configuration;\n\n        public JwtHandler(IConfiguration configuration)\n        {\n            _configuration = configuration;\n        }\n\n        public TokenResource CreateAccessToken(Guid userId, string email, Role role)\n        {\n            var now = DateTime.UtcNow;\n            var claims = new Claim[]\n            {\n            new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()),\n            new Claim(ClaimTypes.Email, email),\n            new Claim(ClaimTypes.Role, role.ToString()),\n            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),\n            new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64),\n            };\n\n            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[\"Tokens:Key\"])),\n                SecurityAlgorithms.HmacSha256);\n            var expiry = now.AddMinutes(double.Parse(_configuration[\"Tokens:AccessExpireMinutes\"]));\n            var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials);\n            var token = new JwtSecurityTokenHandler().WriteToken(jwt);\n\n            return CreateTokenResource(token, expiry.ToTimeStamp());\n        }\n\n        public TokenResource CreateRefreshToken(Guid userId)\n        {\n            var now = DateTime.UtcNow;\n            var claims = new Claim[]\n            {\n            new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),\n            new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64),\n            };\n\n            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[\"Tokens:Key\"])),\n                SecurityAlgorithms.HmacSha256);\n            var expiry = now.AddMinutes(double.Parse(_configuration[\"Tokens:RefreshExpireMinutes\"]));\n            var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials);\n            var token = new JwtSecurityTokenHandler().WriteToken(jwt);\n\n            return CreateTokenResource(token, expiry.ToTimeStamp());\n        }\n\n        private JwtSecurityToken CreateSecurityToken(IEnumerable<Claim> claims, DateTime now, DateTime expiry, SigningCredentials credentials)\n            => new JwtSecurityToken(claims: claims, notBefore: now, expires: expiry, signingCredentials: credentials);\n\n        private static TokenResource CreateTokenResource(string token, long expiry)\n            => new TokenResource { Token = token, Expiry = expiry };\n    }\n```\nAccountService has 2 methods: \n- FacebookLogin\n- CreateAccessTokens\n\nFacebook Login method is taking facebookLoginresource as parameter, then check is facebokToken is null, next step is checking if user with this accesstoken exist in facebook. If everything is ok createaccess token method is calling.\n\nFacebookService has also 2 methods:\n- GetUserFromFacebook\n- GetAsync<T>\n\nfirst method is taking accessToken as parameter and is using this token to check if is in facebook exist user connected with this token. If facebook return basic information about this user is creating a facebookUser resource witch is returning to access token.\n\nJWTService has method responsible for creating JwtTokens, more information about it you can find in my other tutorial:\n[JwtTokens](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api)\n\nLast part is creating a new Controller\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png)\n</center>\n\n```\n        private readonly AccountService _accountService;\n\n        public AccountController(AccountService accountService)\n        {\n            _accountService = accountService;\n        }\n\n        [HttpPost]\n        [Route(\"account/login/facebook\")]\n        public async Task<IActionResult> FacebookLoginAsync([FromBody] FacebookLoginResource resource)\n        {\n            var authorizationTokens = await _accountService.FacebookLoginAsync(resource);\n            return Ok(authorizationTokens);\n        }\n```\n\nThis controller has only one method for taking facebookLoginResource and returning a authorization tokens.\n\n\n#### Curriculum\n\n- [Saving image in database](https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0)\n- [Asp.Net Core with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core)\n- [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0)\n- [Manage Refresh token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api)\n- [Custom error handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0)\n    \n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@babelek/how-to-create-facebook-login-in-asp-net-core-web-api\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":17620347,\"name\":\"Home\",\"full_name\":\"aspnet/Home\",\"html_url\":\"https://github.com/aspnet/Home\",\"fork\":false,\"owner\":{\"login\":\"aspnet\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopina-io\",\"tutorial\",\"facebook\"],\"users\":[\"babelek\"],\"links\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png\",\"https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png\",\"https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0\",\"https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core\",\"https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0\",\"https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0\"],\"image\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png\"],\"moderator\":{\"account\":\"creon\",\"time\":\"2018-03-19T14:51:35.026Z\",\"reviewed\":true,\"pending\":false,\"flagged\":false},\"questions\":[{\"question\":\"Is the project description formal?\",\"answers\":[{\"value\":\"Yes it’s straight to the point\",\"selected\":true,\"score\":10},{\"value\":\"Need more description \",\"selected\":false,\"score\":5},{\"value\":\"Not too descriptive\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is the language / grammar correct?\",\"answers\":[{\"value\":\"Yes\",\"selected\":true,\"score\":20},{\"value\":\"A few mistakes\",\"selected\":false,\"score\":10},{\"value\":\"It's pretty bad\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Was the template followed?\",\"answers\":[{\"value\":\"Yes\",\"selected\":true,\"score\":10},{\"value\":\"Partially\",\"selected\":false,\"score\":5},{\"value\":\"No\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is there information about the additional frameworks?\",\"answers\":[{\"value\":\"Yes, everything is explained\",\"selected\":true,\"score\":5},{\"value\":\"Yes, but not enough\",\"selected\":false,\"score\":3},{\"value\":\"No details at all\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is there code in the tutorial?\",\"answers\":[{\"value\":\"Yes, and it’s well explained\",\"selected\":true,\"score\":5},{\"value\":\"Yes, but no explanation\",\"selected\":false,\"score\":3},{\"value\":\"No\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is the tutorial explains technical aspects well enough?\",\"answers\":[{\"value\":\"Yes, it teaches how and why about technical aspects\",\"selected\":true,\"score\":5},{\"value\":\"Yes, but it’s not good/enough\",\"selected\":false,\"score\":3},{\"value\":\"No, it explains poorly\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is the tutorial general and dense enough?\",\"answers\":[{\"value\":\"Yes, it’s general and dense\",\"selected\":true,\"score\":5},{\"value\":\"Kinda, it might be more generalized\",\"selected\":false,\"score\":3},{\"value\":\"No, it’s sliced unnecessarily to keep part number high\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is there an outline for the tutorial content at the beginning of the post\",\"answers\":[{\"value\":\"Yes, there is a well prepared outline in “What will I learn?” or another outline section\",\"selected\":true,\"score\":5},{\"value\":\"Yes, but there is no proper listing for every step of the tutorial or it’s not detailed enough\",\"selected\":false,\"score\":3},{\"value\":\"No, there is no outline for the steps.\",\"selected\":false,\"score\":0}],\"selected\":0},{\"question\":\"Is the visual content of good quality?\",\"answers\":[{\"value\":\"Yes\",\"selected\":false,\"score\":5},{\"value\":\"Yes, but bad quality\",\"selected\":false,\"score\":3},{\"value\":\"No\",\"selected\":true,\"score\":0}],\"selected\":2},{\"question\":\"Is this a tutorial series?\",\"answers\":[{\"value\":\"Yes\",\"selected\":false,\"score\":5},{\"value\":\"Yes, but first part\",\"selected\":false,\"score\":3},{\"value\":\"No\",\"selected\":true,\"score\":0}],\"selected\":2},{\"question\":\"Is the tutorial post structured?\",\"answers\":[{\"value\":\"Yes\",\"selected\":true,\"score\":5},{\"value\":\"Not so good\",\"selected\":false,\"score\":3},{\"value\":\"No\",\"selected\":false,\"score\":0}],\"selected\":0}],\"score\":49}"
    }
  ]
}
2018/03/18 17:10:45
curatorbabelek
reward2.041148 VESTS
comment authorpiach
comment permlinksocial-meal-social-application-add-login-by-facebook
Transaction InfoBlock #20788703/Virtual Operation #25
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20788703,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 25,
  "timestamp": "2018-03-18T17:10:45",
  "op": [
    "curation_reward",
    {
      "curator": "babelek",
      "reward": "2.041148 VESTS",
      "comment_author": "piach",
      "comment_permlink": "social-meal-social-application-add-login-by-facebook"
    }
  ]
}
2018/03/17 14:54:30
voterpiach
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20757188/Trx 0b4a0e306bf6c242a45b0bfb2907968c52cd7e58
View Raw JSON Data
{
  "trx_id": "0b4a0e306bf6c242a45b0bfb2907968c52cd7e58",
  "block": 20757188,
  "trx_in_block": 3,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-17T14:54:30",
  "op": [
    "vote",
    {
      "voter": "piach",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/17 14:02:12
voterreewy
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
weight10000 (100.00%)
Transaction InfoBlock #20756143/Trx 2e799e54a0912e16d25c9de42489e3dfa2e704b0
View Raw JSON Data
{
  "trx_id": "2e799e54a0912e16d25c9de42489e3dfa2e704b0",
  "block": 20756143,
  "trx_in_block": 24,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-17T14:02:12",
  "op": [
    "vote",
    {
      "voter": "reewy",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "weight": 10000
    }
  ]
}
2018/03/17 14:01:48
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
max accepted payout1000000.000 SBD
percent steem dollars10000
allow votestrue
allow curation rewardstrue
extensions[[0,{"beneficiaries":[{"account":"utopian.pay","weight":2500}]}]]
Transaction InfoBlock #20756135/Trx 35791e06cfc89b26cddf67e2899afa56b18bc839
View Raw JSON Data
{
  "trx_id": "35791e06cfc89b26cddf67e2899afa56b18bc839",
  "block": 20756135,
  "trx_in_block": 36,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-17T14:01:48",
  "op": [
    "comment_options",
    {
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "max_accepted_payout": "1000000.000 SBD",
      "percent_steem_dollars": 10000,
      "allow_votes": true,
      "allow_curation_rewards": true,
      "extensions": [
        [
          0,
          {
            "beneficiaries": [
              {
                "account": "utopian.pay",
                "weight": 2500
              }
            ]
          }
        ]
      ]
    }
  ]
}
2018/03/17 14:01:48
parent author
parent permlinkutopian-io
authorbabelek
permlinkhow-to-create-facebook-login-in-asp-net-core-web-api
titleHow to create facebook login in ASP.NET Core Web API
body #### What Will I Learn? - How to use Facebook API - How to create facebook login to your application - How to use JWT tokens #### Requirements - C# - ASP.NET Core - Visual Studio 2015+/ Visual Studio Code #### Difficulty - Intermediate #### Tutorial Contents In this tutorial I will present how to create logic for Facebook login, using ASP.NET Core Web API. I will show you how to make full service and REST communication with another part application witch can be mobile application or web application. At the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017. <center>![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg) </center> <center>![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg) </center> ### How will it work? When user click in the mobile application that he want to login by facebook, mobile application will send login request to facebook API, when credentials are correctly he will receive accessToken from facebook, this token is sending to our API where our API will send to facebook API request for identify user by accessToken. If everything will be ok facebook will return all information about particular user. Our service will create ours tokens and return this to mobile application. Since then mobile appplication will be using our access token for all request. In the new project I will create new folder with 4 classes. It will be Resource classes, in this classes we will define the models, witch we will be receiving or sending by REST. <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png) </center> I created 4 classes: - FacebookLoginresource - FacebookUserResource - TokenResource - AuthorizationTokenResource First and second class will be used for facebook login, next 2 classes will be used for authorization particular user in our application using JWT Tokens. FacebookLoginResource: ``` public class FacebookLoginResource { [Required] [StringLength(255)] public string facebookToken { get; set; } } ``` FacebookUserResource ``` public class FacebookUserResource { public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string Picture { get; set; } } ``` TokenResource ``` public class TokenResource { public string Token { get; set; } public long Expiry { get; set; } } ``` AuthorizationTokenResource ``` public class AuthorizationTokensResource { public TokenResource AccessToken { get; set; } public TokenResource RefreshToken { get; set; } } ``` Next step is creating a couple of services responsible for logic. I will create 3 service, one for communication with our mobile application, second for communication with facebook API, and third for creating JWT tokens. <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png) </center> AccountService ``` public class AccountService { private readonly FacebookService _facebookService; private readonly JwtHandler _jwtHandler; public AccountService(FacebookService facebookService, JwtHandler jwtHandler) { _facebookService = facebookService; _jwtHandler = jwtHandler; } public async Task<AuthorizationTokensResource> FacebookLoginAsync(FacebookLoginResource facebookLoginResource) { if (string.IsNullOrEmpty(facebookLoginResource.facebookToken)) { throw new Exception("Token is null or empty"); } var facebookUser = await _facebookService.GetUserFromFacebookAsync(facebookLoginResource.facebookToken); var domainUser = await unitOfWork.Users.GetAsync(facebookUser.Email); return await CreateAccessTokens(domainUser, facebookLoginResource.DeviceId, facebookLoginResource.DeviceName); } private async Task<AuthorizationTokensResource> CreateAccessTokens(User user, string deviceId, string deviceName) { var accessToken = _jwtHandler.CreateAccessToken(user.Id, user.Email, user.Role); var refreshToken = _jwtHandler.CreateRefreshToken(user.Id); return new AuthorizationTokensResource { AccessToken = accessToken, RefreshToken = refreshToken }; } } ``` FacebookService ``` public class FacebookService { private readonly HttpClient _httpClient; public FacebookService() { _httpClient = new HttpClient { BaseAddress = new Uri("https://graph.facebook.com/v2.8/") }; _httpClient.DefaultRequestHeaders .Accept .Add(new MediaTypeWithQualityHeaderValue("application/json")); } public async Task<FacebookUserResource> GetUserFromFacebookAsync(string facebookToken) { var result = await GetAsync<dynamic>(facebookToken, "me", "fields=first_name,last_name,email,picture.width(100).height(100)"); if (result == null) { throw new Exception("User from this token not exist"); } var account = new FacebookUserResource() { Email = result.email, FirstName = result.first_name, LastName = result.last_name, Picture = result.picture.data.url }; return account; } private async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null) { var response = await _httpClient.GetAsync($"{endpoint}?access_token={accessToken}&{args}"); if (!response.IsSuccessStatusCode) return default(T); var result = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<T>(result); } } ``` JwtHandler ``` public class JwtHandler { private readonly IConfiguration _configuration; public JwtHandler(IConfiguration configuration) { _configuration = configuration; } public TokenResource CreateAccessToken(Guid userId, string email, Role role) { var now = DateTime.UtcNow; var claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()), new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Role, role.ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64), }; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"])), SecurityAlgorithms.HmacSha256); var expiry = now.AddMinutes(double.Parse(_configuration["Tokens:AccessExpireMinutes"])); var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials); var token = new JwtSecurityTokenHandler().WriteToken(jwt); return CreateTokenResource(token, expiry.ToTimeStamp()); } public TokenResource CreateRefreshToken(Guid userId) { var now = DateTime.UtcNow; var claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64), }; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"])), SecurityAlgorithms.HmacSha256); var expiry = now.AddMinutes(double.Parse(_configuration["Tokens:RefreshExpireMinutes"])); var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials); var token = new JwtSecurityTokenHandler().WriteToken(jwt); return CreateTokenResource(token, expiry.ToTimeStamp()); } private JwtSecurityToken CreateSecurityToken(IEnumerable<Claim> claims, DateTime now, DateTime expiry, SigningCredentials credentials) => new JwtSecurityToken(claims: claims, notBefore: now, expires: expiry, signingCredentials: credentials); private static TokenResource CreateTokenResource(string token, long expiry) => new TokenResource { Token = token, Expiry = expiry }; } ``` AccountService has 2 methods: - FacebookLogin - CreateAccessTokens Facebook Login method is taking facebookLoginresource as parameter, then check is facebokToken is null, next step is checking if user with this accesstoken exist in facebook. If everything is ok createaccess token method is calling. FacebookService has also 2 methods: - GetUserFromFacebook - GetAsync<T> first method is taking accessToken as parameter and is using this token to check if is in facebook exist user connected with this token. If facebook return basic information about this user is creating a facebookUser resource witch is returning to access token. JWTService has method responsible for creating JwtTokens, more information about it you can find in my other tutorial: [JwtTokens](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api) Last part is creating a new Controller <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png) </center> ``` private readonly AccountService _accountService; public AccountController(AccountService accountService) { _accountService = accountService; } [HttpPost] [Route("account/login/facebook")] public async Task<IActionResult> FacebookLoginAsync([FromBody] FacebookLoginResource resource) { var authorizationTokens = await _accountService.FacebookLoginAsync(resource); return Ok(authorizationTokens); } ``` This controller has only one method for taking facebookLoginResource and returning a authorization tokens. #### Curriculum - [Saving image in database](https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0) - [Asp.Net Core with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core) - [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0) - [Manage Refresh token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api) - [Custom error handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@babelek/how-to-create-facebook-login-in-asp-net-core-web-api">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":17620347,"name":"Home","full_name":"aspnet/Home","html_url":"https://github.com/aspnet/Home","fork":false,"owner":{"login":"aspnet"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","utopina-io","tutorial","facebook"],"users":["babelek"],"links":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png","https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png","https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0","https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core","https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0","https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0"],"image":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png"]}
Transaction InfoBlock #20756135/Trx 35791e06cfc89b26cddf67e2899afa56b18bc839
View Raw JSON Data
{
  "trx_id": "35791e06cfc89b26cddf67e2899afa56b18bc839",
  "block": 20756135,
  "trx_in_block": 36,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-17T14:01:48",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "babelek",
      "permlink": "how-to-create-facebook-login-in-asp-net-core-web-api",
      "title": "How to create facebook login in ASP.NET Core Web API",
      "body": "\n#### What Will I Learn?\n\n- How to use Facebook API\n- How to create facebook login to your application\n- How to use JWT tokens\n\n#### Requirements\n\n- C#\n- ASP.NET Core\n- Visual Studio 2015+/ Visual Studio Code\n\n#### Difficulty\n\n- Intermediate\n\n#### Tutorial Contents\nIn this tutorial I will present how to create logic for Facebook login, using ASP.NET Core Web API. I will show you how to make full service and REST communication with another part application witch can be mobile application or web application. \n\nAt the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017. \n<center>![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg)\n</center>\n\n<center>![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg)\n</center>\n\n### How will it work?\nWhen user click in the mobile application that he want to login by facebook, mobile application will send login request to facebook API,  when credentials are correctly he will receive accessToken from facebook, this token is sending to our API where our API will send to facebook API request for identify user by accessToken. If everything will be ok  facebook will return all information about particular user. Our service will create ours tokens and return this to mobile application. Since then mobile appplication will be using our access token for all request.\n\nIn the new project I will create new folder with 4 classes. It will be Resource classes, in this classes we will define the models, witch we will be receiving or sending by REST.\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png)\n</center>\n\nI created 4 classes:\n- FacebookLoginresource\n- FacebookUserResource\n- TokenResource\n- AuthorizationTokenResource\n\nFirst and second class will be used for facebook login, next 2 classes will be used for authorization particular user in our application using JWT Tokens.\n\nFacebookLoginResource: \n```\n    public class FacebookLoginResource\n    {\n        [Required]\n        [StringLength(255)]\n        public string facebookToken { get; set; }\n    }\n```\nFacebookUserResource\n```\n    public class FacebookUserResource\n    {\n        public string FirstName { get; set; }\n        public string LastName { get; set; }\n        public string Email { get; set; }\n        public string Picture { get; set; }\n    }\n```\n\nTokenResource\n```\n    public class TokenResource\n    {\n        public string Token { get; set; }\n        public long Expiry { get; set; }\n    }\n```\nAuthorizationTokenResource\n```\n    public class AuthorizationTokensResource\n    {\n        public TokenResource AccessToken { get; set; }\n        public TokenResource RefreshToken { get; set; }\n    }\n```\n\nNext step is creating a couple of services responsible for logic. I will create 3 service, one for communication with our mobile application, second for communication with facebook API, and third for creating JWT tokens.\n\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png)\n</center>\n\nAccountService\n```\n public class AccountService\n    {\n        private readonly FacebookService _facebookService;\n        private readonly JwtHandler _jwtHandler;\n\n        public AccountService(FacebookService facebookService, JwtHandler jwtHandler)\n        {\n            _facebookService = facebookService;\n            _jwtHandler = jwtHandler;\n        }\n\n        public async Task<AuthorizationTokensResource> FacebookLoginAsync(FacebookLoginResource facebookLoginResource)\n        {\n            if (string.IsNullOrEmpty(facebookLoginResource.facebookToken))\n            {\n                throw new Exception(\"Token is null or empty\");\n            }\n\n            var facebookUser = await _facebookService.GetUserFromFacebookAsync(facebookLoginResource.facebookToken);\n            var domainUser = await unitOfWork.Users.GetAsync(facebookUser.Email);\n\n            return await CreateAccessTokens(domainUser, facebookLoginResource.DeviceId,\n                facebookLoginResource.DeviceName);\n        }\n\n        private async Task<AuthorizationTokensResource> CreateAccessTokens(User user, string deviceId,\n            string deviceName)\n        {\n            var accessToken = _jwtHandler.CreateAccessToken(user.Id, user.Email, user.Role);\n            var refreshToken = _jwtHandler.CreateRefreshToken(user.Id);\n\n            return new AuthorizationTokensResource { AccessToken = accessToken, RefreshToken = refreshToken };\n        }\n    }\n```\n\nFacebookService\n```\n    public class FacebookService\n    {\n        private readonly HttpClient _httpClient;\n\n        public FacebookService()\n        {\n            _httpClient = new HttpClient\n            {\n                BaseAddress = new Uri(\"https://graph.facebook.com/v2.8/\")\n            };\n            _httpClient.DefaultRequestHeaders\n                .Accept\n                .Add(new MediaTypeWithQualityHeaderValue(\"application/json\"));\n        }\n\n\n        public async Task<FacebookUserResource> GetUserFromFacebookAsync(string facebookToken)\n        {\n            var result = await GetAsync<dynamic>(facebookToken, \"me\", \"fields=first_name,last_name,email,picture.width(100).height(100)\");\n            if (result == null)\n            {\n                throw new Exception(\"User from this token not exist\");\n            }\n\n            var account = new FacebookUserResource()\n            {\n                Email = result.email,\n                FirstName = result.first_name,\n                LastName = result.last_name,\n                Picture = result.picture.data.url\n            };\n\n            return account;\n        }\n\n        private async Task<T> GetAsync<T>(string accessToken, string endpoint, string args = null)\n        {\n            var response = await _httpClient.GetAsync($\"{endpoint}?access_token={accessToken}&{args}\");\n            if (!response.IsSuccessStatusCode)\n                return default(T);\n\n            var result = await response.Content.ReadAsStringAsync();\n\n            return JsonConvert.DeserializeObject<T>(result);\n        }\n    }\n```\nJwtHandler\n```\npublic class JwtHandler\n    {\n        private readonly IConfiguration _configuration;\n\n        public JwtHandler(IConfiguration configuration)\n        {\n            _configuration = configuration;\n        }\n\n        public TokenResource CreateAccessToken(Guid userId, string email, Role role)\n        {\n            var now = DateTime.UtcNow;\n            var claims = new Claim[]\n            {\n            new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()),\n            new Claim(ClaimTypes.Email, email),\n            new Claim(ClaimTypes.Role, role.ToString()),\n            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),\n            new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64),\n            };\n\n            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[\"Tokens:Key\"])),\n                SecurityAlgorithms.HmacSha256);\n            var expiry = now.AddMinutes(double.Parse(_configuration[\"Tokens:AccessExpireMinutes\"]));\n            var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials);\n            var token = new JwtSecurityTokenHandler().WriteToken(jwt);\n\n            return CreateTokenResource(token, expiry.ToTimeStamp());\n        }\n\n        public TokenResource CreateRefreshToken(Guid userId)\n        {\n            var now = DateTime.UtcNow;\n            var claims = new Claim[]\n            {\n            new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.UniqueName, userId.ToString()),\n            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),\n            new Claim(JwtRegisteredClaimNames.Iat, now.ToTimeStamp().ToString(), ClaimValueTypes.Integer64),\n            };\n\n            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[\"Tokens:Key\"])),\n                SecurityAlgorithms.HmacSha256);\n            var expiry = now.AddMinutes(double.Parse(_configuration[\"Tokens:RefreshExpireMinutes\"]));\n            var jwt = CreateSecurityToken(claims, now, expiry, signingCredentials);\n            var token = new JwtSecurityTokenHandler().WriteToken(jwt);\n\n            return CreateTokenResource(token, expiry.ToTimeStamp());\n        }\n\n        private JwtSecurityToken CreateSecurityToken(IEnumerable<Claim> claims, DateTime now, DateTime expiry, SigningCredentials credentials)\n            => new JwtSecurityToken(claims: claims, notBefore: now, expires: expiry, signingCredentials: credentials);\n\n        private static TokenResource CreateTokenResource(string token, long expiry)\n            => new TokenResource { Token = token, Expiry = expiry };\n    }\n```\nAccountService has 2 methods: \n- FacebookLogin\n- CreateAccessTokens\n\nFacebook Login method is taking facebookLoginresource as parameter, then check is facebokToken is null, next step is checking if user with this accesstoken exist in facebook. If everything is ok createaccess token method is calling.\n\nFacebookService has also 2 methods:\n- GetUserFromFacebook\n- GetAsync<T>\n\nfirst method is taking accessToken as parameter and is using this token to check if is in facebook exist user connected with this token. If facebook return basic information about this user is creating a facebookUser resource witch is returning to access token.\n\nJWTService has method responsible for creating JwtTokens, more information about it you can find in my other tutorial:\n[JwtTokens](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api)\n\nLast part is creating a new Controller\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png)\n</center>\n\n```\n        private readonly AccountService _accountService;\n\n        public AccountController(AccountService accountService)\n        {\n            _accountService = accountService;\n        }\n\n        [HttpPost]\n        [Route(\"account/login/facebook\")]\n        public async Task<IActionResult> FacebookLoginAsync([FromBody] FacebookLoginResource resource)\n        {\n            var authorizationTokens = await _accountService.FacebookLoginAsync(resource);\n            return Ok(authorizationTokens);\n        }\n```\n\nThis controller has only one method for taking facebookLoginResource and returning a authorization tokens.\n\n\n#### Curriculum\n\n- [Saving image in database](https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0)\n- [Asp.Net Core with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core)\n- [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0)\n- [Manage Refresh token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api)\n- [Custom error handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0)\n    \n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@babelek/how-to-create-facebook-login-in-asp-net-core-web-api\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":17620347,\"name\":\"Home\",\"full_name\":\"aspnet/Home\",\"html_url\":\"https://github.com/aspnet/Home\",\"fork\":false,\"owner\":{\"login\":\"aspnet\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"utopina-io\",\"tutorial\",\"facebook\"],\"users\":[\"babelek\"],\"links\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png\",\"https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png\",\"https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0\",\"https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core\",\"https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0\",\"https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0\"],\"image\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293291/z0namoxydsjhy5aetk7z.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293312/icufd2b9w51azciobdy6.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521293452/nfhcsswlvytkh3lkn4eo.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521294156/egahz4c37oqknfu96sih.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1521295106/y3x8no59bid5uaplaovv.png\"]}"
    }
  ]
}
2018/03/14 16:31:03
voterbabelek
authorpiach
permlinksocial-meal-social-application-add-login-by-facebook
weight10000 (100.00%)
Transaction InfoBlock #20672834/Trx d6eff353f7355de11aebb4797e556a292b507e9a
View Raw JSON Data
{
  "trx_id": "d6eff353f7355de11aebb4797e556a292b507e9a",
  "block": 20672834,
  "trx_in_block": 85,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-14T16:31:03",
  "op": [
    "vote",
    {
      "voter": "babelek",
      "author": "piach",
      "permlink": "social-meal-social-application-add-login-by-facebook",
      "weight": 10000
    }
  ]
}
hotupvotesent 0.001 SBD to @babelek- "Hi ! Good news ! We have united ! @bigshot + @hotlist + @re-blog + @artcity . Resteem to 40.000+ Followers . + 50 upvote . Send 3 SBD or STEEM to @hotupvote or to any of 4 services , ( URL as memo ) ...."
2018/03/13 21:40:33
fromhotupvote
tobabelek
amount0.001 SBD
memoHi ! Good news ! We have united ! @bigshot + @hotlist + @re-blog + @artcity . Resteem to 40.000+ Followers . + 50 upvote . Send 3 SBD or STEEM to @hotupvote or to any of 4 services , ( URL as memo ) . Service Active
Transaction InfoBlock #20650233/Trx 07bb1de526ef17b5ebf38819e4ae8e1ca2bd045d
View Raw JSON Data
{
  "trx_id": "07bb1de526ef17b5ebf38819e4ae8e1ca2bd045d",
  "block": 20650233,
  "trx_in_block": 9,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-13T21:40:33",
  "op": [
    "transfer",
    {
      "from": "hotupvote",
      "to": "babelek",
      "amount": "0.001 SBD",
      "memo": "Hi ! Good news ! We have united ! @bigshot + @hotlist + @re-blog + @artcity . Resteem to 40.000+ Followers . + 50 upvote . Send 3 SBD or STEEM to @hotupvote or to any of 4 services , ( URL as memo ) . Service Active"
    }
  ]
}
babelekreceived 0.000 STEEM from power down installment (0.000 SP)
2018/03/11 18:37:45
from accountbabelek
to accountbabelek
withdrawn0.000001 VESTS
deposited0.000 STEEM
Transaction InfoBlock #20589028/Virtual Operation #31
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20589028,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 31,
  "timestamp": "2018-03-11T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "0.000001 VESTS",
      "deposited": "0.000 STEEM"
    }
  ]
}
2018/03/10 12:16:39
curatorbabelek
reward2.042029 VESTS
comment authorpiach
comment permlinksocial-meal-social-application-add-searching-method-and-change-database-structure
Transaction InfoBlock #20552682/Virtual Operation #18
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20552682,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 18,
  "timestamp": "2018-03-10T12:16:39",
  "op": [
    "curation_reward",
    {
      "curator": "babelek",
      "reward": "2.042029 VESTS",
      "comment_author": "piach",
      "comment_permlink": "social-meal-social-application-add-searching-method-and-change-database-structure"
    }
  ]
}
2018/03/05 22:43:24
voterbabelek
authorpiach
permlinksocial-meal-social-application-add-searching-method-and-change-database-structure
weight10000 (100.00%)
Transaction InfoBlock #20421435/Trx e198f85a624c7dea1b3fe0d1fa0c8a89ec718f34
View Raw JSON Data
{
  "trx_id": "e198f85a624c7dea1b3fe0d1fa0c8a89ec718f34",
  "block": 20421435,
  "trx_in_block": 49,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-03-05T22:43:24",
  "op": [
    "vote",
    {
      "voter": "babelek",
      "author": "piach",
      "permlink": "social-meal-social-application-add-searching-method-and-change-database-structure",
      "weight": 10000
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/03/04 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #20387731/Virtual Operation #21
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20387731,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 21,
  "timestamp": "2018-03-04T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
re-blogsent 0.001 SBD to @babelek- "Resteem to 11.000+ followers and upvote 100%. Send 1 SBD or STEEM to @re-blog, URL as memo. Service Active"
2018/02/27 22:15:42
fromre-blog
tobabelek
amount0.001 SBD
memoResteem to 11.000+ followers and upvote 100%. Send 1 SBD or STEEM to @re-blog, URL as memo. Service Active
Transaction InfoBlock #20248152/Trx 9ff8dd331f27d8f9833d4185053a8ad49abb7d5b
View Raw JSON Data
{
  "trx_id": "9ff8dd331f27d8f9833d4185053a8ad49abb7d5b",
  "block": 20248152,
  "trx_in_block": 48,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-02-27T22:15:42",
  "op": [
    "transfer",
    {
      "from": "re-blog",
      "to": "babelek",
      "amount": "0.001 SBD",
      "memo": "Resteem to 11.000+ followers and upvote 100%. Send 1 SBD or STEEM to @re-blog, URL as memo. Service Active"
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/02/25 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #20186363/Virtual Operation #23
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 20186363,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 23,
  "timestamp": "2018-02-25T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/02/18 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #19984817/Virtual Operation #7
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19984817,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 7,
  "timestamp": "2018-02-18T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/02/11 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #19783374/Virtual Operation #17
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19783374,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 17,
  "timestamp": "2018-02-11T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/02/04 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #19582110/Virtual Operation #27
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19582110,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 27,
  "timestamp": "2018-02-04T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
babelekpublished a new post: steem-on-binance
2018/02/01 09:55:27
parent author
parent permlinksteem
authorbabelek
permlinksteem-on-binance
titleSteem on Binance!
bodyToday Binance informed users that from today is available trading STEEM: - STEEM/BTC - STEEM/ETH - STEEM/BNB More info: https://support.binance.com/hc/en-us/articles/360000492012
json metadata{"tags":["steem","cryptocurency","crypto","steemit"],"links":["https://support.binance.com/hc/en-us/articles/360000492012"],"app":"steemit/0.1","format":"markdown"}
Transaction InfoBlock #19485474/Trx 45f3b3a59bf5a003f35b7b44765b6d2c0f536e58
View Raw JSON Data
{
  "trx_id": "45f3b3a59bf5a003f35b7b44765b6d2c0f536e58",
  "block": 19485474,
  "trx_in_block": 5,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-02-01T09:55:27",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "steem",
      "author": "babelek",
      "permlink": "steem-on-binance",
      "title": "Steem on Binance!",
      "body": "Today Binance informed users that from today is available trading STEEM:\n\n- STEEM/BTC\n- STEEM/ETH\n- STEEM/BNB\n\nMore info: https://support.binance.com/hc/en-us/articles/360000492012",
      "json_metadata": "{\"tags\":[\"steem\",\"cryptocurency\",\"crypto\",\"steemit\"],\"links\":[\"https://support.binance.com/hc/en-us/articles/360000492012\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}"
    }
  ]
}
steemdelegated 2.100 SP to @babelek
2018/01/31 22:57:54
delegatorsteem
delegateebabelek
vesting shares3420.263054 VESTS
Transaction InfoBlock #19472350/Trx 40b1f896718d415a714e404b0f747a9814877dd7
View Raw JSON Data
{
  "trx_id": "40b1f896718d415a714e404b0f747a9814877dd7",
  "block": 19472350,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-31T22:57:54",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "babelek",
      "vesting_shares": "3420.263054 VESTS"
    }
  ]
}
babeleksent 10.448 SBD to @bittrex- "e848f4d3e52e46c0bcd"
2018/01/31 21:43:51
frombabelek
tobittrex
amount10.448 SBD
memoe848f4d3e52e46c0bcd
Transaction InfoBlock #19470870/Trx 95d4cbf068a8ee27f2c9b1b0996204a76ae304af
View Raw JSON Data
{
  "trx_id": "95d4cbf068a8ee27f2c9b1b0996204a76ae304af",
  "block": 19470870,
  "trx_in_block": 40,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-31T21:43:51",
  "op": [
    "transfer",
    {
      "from": "babelek",
      "to": "bittrex",
      "amount": "10.448 SBD",
      "memo": "e848f4d3e52e46c0bcd"
    }
  ]
}
babelekclaimed reward balance: 10.448 SBD, 2.485 SP
2018/01/31 21:43:30
accountbabelek
reward steem0.000 STEEM
reward sbd10.448 SBD
reward vests4047.067064 VESTS
Transaction InfoBlock #19470863/Trx fb3b898edb1769041556d1f2ef3942c818821717
View Raw JSON Data
{
  "trx_id": "fb3b898edb1769041556d1f2ef3942c818821717",
  "block": 19470863,
  "trx_in_block": 41,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-31T21:43:30",
  "op": [
    "claim_reward_balance",
    {
      "account": "babelek",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "10.448 SBD",
      "reward_vests": "4047.067064 VESTS"
    }
  ]
}
babelekreceived 10.448 SBD, 2.485 SP author reward for @babelek / how-to-save-image-on-the-serwer-using-asp-net-core-2-0
2018/01/31 21:34:30
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
sbd payout10.448 SBD
steem payout0.000 STEEM
vesting payout4047.067064 VESTS
Transaction InfoBlock #19470682/Virtual Operation #18
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19470682,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 18,
  "timestamp": "2018-01-31T21:34:30",
  "op": [
    "author_reward",
    {
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "sbd_payout": "10.448 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "4047.067064 VESTS"
    }
  ]
}
utopian.payreceived 1.656 SP benefactor reward from @babelek
2018/01/31 21:34:30
benefactorutopian.pay
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2696.680682 VESTS
Transaction InfoBlock #19470682/Virtual Operation #17
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19470682,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 17,
  "timestamp": "2018-01-31T21:34:30",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2696.680682 VESTS"
    }
  ]
}
peter.gokiupvoted (100.00%) @babelek / hello-steemit
2018/01/29 16:33:48
voterpeter.goki
authorbabelek
permlinkhello-steemit
weight10000 (100.00%)
Transaction InfoBlock #19407131/Trx 2979b600c41604a5b6591a7e79588d0efd5672c3
View Raw JSON Data
{
  "trx_id": "2979b600c41604a5b6591a7e79588d0efd5672c3",
  "block": 19407131,
  "trx_in_block": 42,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-29T16:33:48",
  "op": [
    "vote",
    {
      "voter": "peter.goki",
      "author": "babelek",
      "permlink": "hello-steemit",
      "weight": 10000
    }
  ]
}
2018/01/29 16:31:54
voterpeter.goki
authorbabelek
permlinkmy-daughter-for-the-first-time-ride-horse
weight10000 (100.00%)
Transaction InfoBlock #19407093/Trx 847afad59719580724c9176106356f0878f7c7ab
View Raw JSON Data
{
  "trx_id": "847afad59719580724c9176106356f0878f7c7ab",
  "block": 19407093,
  "trx_in_block": 22,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-29T16:31:54",
  "op": [
    "vote",
    {
      "voter": "peter.goki",
      "author": "babelek",
      "permlink": "my-daughter-for-the-first-time-ride-horse",
      "weight": 10000
    }
  ]
}
steemdelegated 4.588 SP to @babelek
2018/01/29 00:26:03
delegatorsteem
delegateebabelek
vesting shares7471.989448 VESTS
Transaction InfoBlock #19387782/Trx ae21127c1682c91bc247a786b305def0acbc8087
View Raw JSON Data
{
  "trx_id": "ae21127c1682c91bc247a786b305def0acbc8087",
  "block": 19387782,
  "trx_in_block": 15,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-29T00:26:03",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "babelek",
      "vesting_shares": "7471.989448 VESTS"
    }
  ]
}
babeleksent 12.259 SBD to @bittrex- "e848f4d3e52e46c0bcd"
2018/01/28 22:50:12
frombabelek
tobittrex
amount12.259 SBD
memoe848f4d3e52e46c0bcd
Transaction InfoBlock #19385866/Trx caff000e7023247644c4146e741302bc4e9649c4
View Raw JSON Data
{
  "trx_id": "caff000e7023247644c4146e741302bc4e9649c4",
  "block": 19385866,
  "trx_in_block": 6,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-28T22:50:12",
  "op": [
    "transfer",
    {
      "from": "babelek",
      "to": "bittrex",
      "amount": "12.259 SBD",
      "memo": "e848f4d3e52e46c0bcd"
    }
  ]
}
babelekclaimed reward balance: 12.259 SBD, 2.552 SP
2018/01/28 22:49:39
accountbabelek
reward steem0.000 STEEM
reward sbd12.259 SBD
reward vests4156.139664 VESTS
Transaction InfoBlock #19385855/Trx a91d29fb6566c6c4025bcd6e7914a9fb8254a1cf
View Raw JSON Data
{
  "trx_id": "a91d29fb6566c6c4025bcd6e7914a9fb8254a1cf",
  "block": 19385855,
  "trx_in_block": 43,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-28T22:49:39",
  "op": [
    "claim_reward_balance",
    {
      "account": "babelek",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "12.259 SBD",
      "reward_vests": "4156.139664 VESTS"
    }
  ]
}
babelekreceived 12.259 SBD, 2.552 SP author reward for @babelek / how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api
2018/01/28 22:43:48
authorbabelek
permlinkhow-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api
sbd payout12.259 SBD
steem payout0.000 STEEM
vesting payout4156.139664 VESTS
Transaction InfoBlock #19385737/Virtual Operation #11
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19385737,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 11,
  "timestamp": "2018-01-28T22:43:48",
  "op": [
    "author_reward",
    {
      "author": "babelek",
      "permlink": "how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api",
      "sbd_payout": "12.259 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "4156.139664 VESTS"
    }
  ]
}
utopian.payreceived 1.700 SP benefactor reward from @babelek
2018/01/28 22:43:48
benefactorutopian.pay
authorbabelek
permlinkhow-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2768.713424 VESTS
Transaction InfoBlock #19385737/Virtual Operation #10
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19385737,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 10,
  "timestamp": "2018-01-28T22:43:48",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "babelek",
      "permlink": "how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2768.713424 VESTS"
    }
  ]
}
babelekreceived 0.219 STEEM from power down installment (0.276 SP)
2018/01/28 18:37:45
from accountbabelek
to accountbabelek
withdrawn449.033939 VESTS
deposited0.219 STEEM
Transaction InfoBlock #19380818/Virtual Operation #17
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19380818,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 17,
  "timestamp": "2018-01-28T18:37:45",
  "op": [
    "fill_vesting_withdraw",
    {
      "from_account": "babelek",
      "to_account": "babelek",
      "withdrawn": "449.033939 VESTS",
      "deposited": "0.219 STEEM"
    }
  ]
}
steemdelegated 6.866 SP to @babelek
2018/01/27 16:08:45
delegatorsteem
delegateebabelek
vesting shares11181.191373 VESTS
Transaction InfoBlock #19349047/Trx fec394dbe122320f332b7639ed431438c3ca1629
View Raw JSON Data
{
  "trx_id": "fec394dbe122320f332b7639ed431438c3ca1629",
  "block": 19349047,
  "trx_in_block": 31,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-27T16:08:45",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "babelek",
      "vesting_shares": "11181.191373 VESTS"
    }
  ]
}
babeleksent 12.417 SBD to @bittrex- "e848f4d3e52e46c0bcd"
2018/01/27 15:58:00
frombabelek
tobittrex
amount12.417 SBD
memoe848f4d3e52e46c0bcd
Transaction InfoBlock #19348832/Trx aff25d595f26ba2acb2a8761ba711d06eef744d3
View Raw JSON Data
{
  "trx_id": "aff25d595f26ba2acb2a8761ba711d06eef744d3",
  "block": 19348832,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-27T15:58:00",
  "op": [
    "transfer",
    {
      "from": "babelek",
      "to": "bittrex",
      "amount": "12.417 SBD",
      "memo": "e848f4d3e52e46c0bcd"
    }
  ]
}
babelekclaimed reward balance: 12.417 SBD, 2.593 SP
2018/01/27 15:57:27
accountbabelek
reward steem0.000 STEEM
reward sbd12.417 SBD
reward vests4221.914700 VESTS
Transaction InfoBlock #19348821/Trx 78785b2385c29b78f413b45c7a0d96c2ffdb070f
View Raw JSON Data
{
  "trx_id": "78785b2385c29b78f413b45c7a0d96c2ffdb070f",
  "block": 19348821,
  "trx_in_block": 37,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-27T15:57:27",
  "op": [
    "claim_reward_balance",
    {
      "account": "babelek",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "12.417 SBD",
      "reward_vests": "4221.914700 VESTS"
    }
  ]
}
2018/01/27 14:01:39
authorbabelek
permlinkhow-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core
sbd payout12.417 SBD
steem payout0.000 STEEM
vesting payout4221.914700 VESTS
Transaction InfoBlock #19346506/Virtual Operation #15
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19346506,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 15,
  "timestamp": "2018-01-27T14:01:39",
  "op": [
    "author_reward",
    {
      "author": "babelek",
      "permlink": "how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core",
      "sbd_payout": "12.417 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "4221.914700 VESTS"
    }
  ]
}
utopian.payreceived 1.728 SP benefactor reward from @babelek
2018/01/27 14:01:39
benefactorutopian.pay
authorbabelek
permlinkhow-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core
sbd payout0.000 SBD
steem payout0.000 STEEM
vesting payout2813.927636 VESTS
Transaction InfoBlock #19346506/Virtual Operation #14
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19346506,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 14,
  "timestamp": "2018-01-27T14:01:39",
  "op": [
    "comment_benefactor_reward",
    {
      "benefactor": "utopian.pay",
      "author": "babelek",
      "permlink": "how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core",
      "sbd_payout": "0.000 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "2813.927636 VESTS"
    }
  ]
}
2018/01/26 07:24:12
voternanettewalsh
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
weight10000 (100.00%)
Transaction InfoBlock #19309795/Trx 02034013cea8c331c2ed0b220f13c6866ab170e3
View Raw JSON Data
{
  "trx_id": "02034013cea8c331c2ed0b220f13c6866ab170e3",
  "block": 19309795,
  "trx_in_block": 33,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T07:24:12",
  "op": [
    "vote",
    {
      "voter": "nanettewalsh",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "weight": 10000
    }
  ]
}
2018/01/26 07:05:30
parent authorbabelek
parent permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
authorutopian-io
permlinkre-babelek-how-to-save-image-on-the-serwer-using-asp-net-core-2-0-20180126t070527678z
title
body### Hey @babelek I am @utopian-io. I have just upvoted you! #### Achievements - You have less than 500 followers. Just gave you a gift to help you succeed! - Seems like you contribute quite often. AMAZING! #### Suggestions - Contribute more often to get higher and higher rewards. I wish to see you often! - Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck! #### Get Noticed! - Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions! #### Community-Driven Witness! I am the first and only Steem Community-Driven Witness. <a href="https://discord.gg/zTrEMqB">Participate on Discord</a>. Lets GROW TOGETHER! - <a href="https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1">Vote for my Witness With SteemConnect</a> - <a href="https://v2.steemconnect.com/sign/account-witness-proxy?proxy=utopian-io&approve=1">Proxy vote to Utopian Witness with SteemConnect</a> - Or vote/proxy on <a href="https://steemit.com/~witnesses">Steemit Witnesses</a> [![mooncryption-utopian-witness-gif](https://steemitimages.com/DQmYPUuQRptAqNBCQRwQjKWAqWU3zJkL3RXVUtEKVury8up/mooncryption-s-utopian-io-witness-gif.gif)](https://steemit.com/~witnesses) **Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #19309421/Trx a1fe8ff141a3958bb9bde07649aef8053a34da27
View Raw JSON Data
{
  "trx_id": "a1fe8ff141a3958bb9bde07649aef8053a34da27",
  "block": 19309421,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T07:05:30",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "author": "utopian-io",
      "permlink": "re-babelek-how-to-save-image-on-the-serwer-using-asp-net-core-2-0-20180126t070527678z",
      "title": "",
      "body": "### Hey @babelek I am @utopian-io. I have just upvoted you!\n#### Achievements\n- You have less than 500 followers. Just gave you a gift to help you succeed!\n- Seems like you contribute quite often. AMAZING!\n#### Suggestions\n- Contribute more often to get higher and higher rewards. I wish to see you often!\n- Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck!\n#### Get Noticed!\n- Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions!\n#### Community-Driven Witness!\nI am the first and only Steem Community-Driven Witness. <a href=\"https://discord.gg/zTrEMqB\">Participate on Discord</a>. Lets GROW TOGETHER!\n- <a href=\"https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1\">Vote for my Witness With SteemConnect</a>\n- <a href=\"https://v2.steemconnect.com/sign/account-witness-proxy?proxy=utopian-io&approve=1\">Proxy vote to Utopian Witness with SteemConnect</a>\n- Or vote/proxy on <a href=\"https://steemit.com/~witnesses\">Steemit Witnesses</a>\n\n[![mooncryption-utopian-witness-gif](https://steemitimages.com/DQmYPUuQRptAqNBCQRwQjKWAqWU3zJkL3RXVUtEKVury8up/mooncryption-s-utopian-io-witness-gif.gif)](https://steemit.com/~witnesses)\n\n**Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/01/26 07:05:24
voterutopian-io
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
weight269 (2.69%)
Transaction InfoBlock #19309419/Trx ba751b805cc97c496171c4e21ce9fdf814058031
View Raw JSON Data
{
  "trx_id": "ba751b805cc97c496171c4e21ce9fdf814058031",
  "block": 19309419,
  "trx_in_block": 26,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T07:05:24",
  "op": [
    "vote",
    {
      "voter": "utopian-io",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "weight": 269
    }
  ]
}
2018/01/26 03:36:30
voteryuxid
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
weight2500 (25.00%)
Transaction InfoBlock #19305244/Trx c9def99ee657efe9f0cd58fbaf04b802abeab0d0
View Raw JSON Data
{
  "trx_id": "c9def99ee657efe9f0cd58fbaf04b802abeab0d0",
  "block": 19305244,
  "trx_in_block": 73,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T03:36:30",
  "op": [
    "vote",
    {
      "voter": "yuxid",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "weight": 2500
    }
  ]
}
2018/01/26 03:31:12
parent authorbabelek
parent permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
authorrufans
permlinkre-babelek-how-to-save-image-on-the-serwer-using-asp-net-core-2-0-20180126t033103105z
title
bodyThank you for the contribution. It has been approved. You can contact us on [Discord](https://discord.gg/uTyJkNm). **[[utopian-moderator]](https://utopian.io/moderators)**
json metadata{"tags":["utopian-io"],"community":"utopian","app":"utopian/1.0.0"}
Transaction InfoBlock #19305138/Trx 277152f6261ff4a6165b123200b32cc4b4cc4424
View Raw JSON Data
{
  "trx_id": "277152f6261ff4a6165b123200b32cc4b4cc4424",
  "block": 19305138,
  "trx_in_block": 18,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T03:31:12",
  "op": [
    "comment",
    {
      "parent_author": "babelek",
      "parent_permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "author": "rufans",
      "permlink": "re-babelek-how-to-save-image-on-the-serwer-using-asp-net-core-2-0-20180126t033103105z",
      "title": "",
      "body": "Thank you for the contribution. It has been approved.\n\nYou can contact us on [Discord](https://discord.gg/uTyJkNm).\n**[[utopian-moderator]](https://utopian.io/moderators)**",
      "json_metadata": "{\"tags\":[\"utopian-io\"],\"community\":\"utopian\",\"app\":\"utopian/1.0.0\"}"
    }
  ]
}
2018/01/26 03:30:54
parent author
parent permlinkutopian-io
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
titleHow to save image on the serwer using ASP.NET Core 2.0
body #### What Will I Learn? - You will learn how to correctly save image on the server using ASP.NET Core. I will show You how to save original image and his smaller copy. I will use avatar and thumbnail as example. What is more this tutorial will show you how to save image made directly from smartphone, set him correctly position and save, resize and delete old. #### Requirements - C# - ASP.NET - Visual Studio 2015+/Visual Studio Core #### Difficulty - Intermediate #### Tutorial Contents At the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017. ![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg) ![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg) In the new project I will create new folder with one class. It will be ImageService class, in this class we will define the whole logic for image management. <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png) </center> In this service we have main function witch is: SaveImage. This function is define in this way: ``` public async Task<string> SaveImage(User user, Stream imageStream) { if (imageStream == null || imageStream.Length == 0) { throw new ServiceException(ServiceErrorCodes.InvalidPhoto, "There is no photo."); } if (imageStream.Length > 5120000) { throw new ServiceException(ServiceErrorCodes.InvalidPhoto, "Photo cannot be bigger than 5120000 bytes."); } string[] photos; try { photos = SetThumbnails(imageStream); } catch (ArgumentException) { throw new ServiceException(ServiceErrorCodes.InvalidPhoto, "Invalid file format."); } if (photos != null) { bool userHasThumbnail = user.WebThumbnail != null; var oldPhoto = user.WebThumbnail; var oldThumbnail = user.Thumbnail; if (userHasThumbnail) { DeletePhotoIfExist(oldPhoto); DeletePhotoIfExist(oldThumbnail); } } return user.Thumbnail; } ``` As parameters take image as stream and user. User because we will save this image as his avatar. At the beginning we have to check if stream i null or has no length, then if the image is too big. In this function we have few more functions, the first one, and the most important is "SetThumbnails()" ``` public string[] SetThumbnails(Stream imageStream) { var originalImage = Image.FromStream(imageStream); if (!ValidateImageFormat(originalImage)) { throw new ArgumentException(); } SetCorrectOrientation(originalImage); var photoId = Guid.NewGuid().ToString(); var mobileThumbnail = $"Content/Photos/Users/Thumbnails/500/{photoId}.jpg"; var webThumbnail = $"Content/Photos/Users/Thumbnails/100/{photoId}.jpg"; CreateAndSaveThumbnail(originalImage, 500, mobileThumbnail); CreateAndSaveThumbnail(originalImage, 100, webThumbnail); originalImage.Dispose(); return new[] { webThumbnail, mobileThumbnail }; } ``` As I said earlier we will validate our image if he has correctly format and right position. Validation image format: ``` private static bool ValidateImageFormat(Image image) { if (ImageFormat.Jpeg.Equals(image.RawFormat)) { return true; } if (ImageFormat.Png.Equals(image.RawFormat)) { return true; } if (ImageFormat.Gif.Equals(image.RawFormat)) { return true; } if (ImageFormat.Bmp.Equals(image.RawFormat)) { return true; } return false; } ``` Now we have to set correct image orientation, I'm using this function because photos made by samsung and directly save on the server are rotate about 90 degrees, I don't want to display photos like this, so I rotate them. ``` private static void SetCorrectOrientation(Image image) { //property id = 274 describe EXIF orientation parameter if (Array.IndexOf(image.PropertyIdList, 274) > -1) { var orientation = (int)image.GetPropertyItem(274).Value[0]; switch (orientation) { case 1: // No rotation required. break; case 2: image.RotateFlip(RotateFlipType.RotateNoneFlipX); break; case 3: image.RotateFlip(RotateFlipType.Rotate180FlipNone); break; case 4: image.RotateFlip(RotateFlipType.Rotate180FlipX); break; case 5: image.RotateFlip(RotateFlipType.Rotate90FlipX); break; case 6: image.RotateFlip(RotateFlipType.Rotate90FlipNone); break; case 7: image.RotateFlip(RotateFlipType.Rotate270FlipX); break; case 8: image.RotateFlip(RotateFlipType.Rotate270FlipNone); break; } // This EXIF data is now invalid and should be removed. image.RemovePropertyItem(274); } } ``` If we have correctly oriented photo we can save it. ``` private void CreateAndSaveThumbnail(Image image, int size, string thumbnailPath) { var thumbnailSize = GetThumbnailSize(image, size); using (var bitmap = ResizeImage(image, thumbnailSize.Width, thumbnailSize.Height)) { bitmap.Save(_serverPath.ServerPath + thumbnailPath, ImageFormat.Jpeg); } } ``` We will save original and one smaller photo, so we have to resize it: ``` private static Size GetThumbnailSize(Image original, int size = 500) { var originalWidth = original.Width; var originalHeight = original.Height; double factor; if (originalWidth > originalHeight) { factor = (double)size / originalWidth; } else { factor = (double)size / originalHeight; } return new Size((int)(originalWidth * factor), (int)(originalHeight * factor)); } ``` ``` private Bitmap ResizeImage(Image image, int width, int height) { var result = new Bitmap(width, height); using (var graphics = Graphics.FromImage(result)) { graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.DrawImage(image, 0, 0, result.Width, result.Height); } return result; } ``` Now we have complete logic for saving images, at the end I will show you how to delete photos from server: ``` public void DeletePhotoIfExist(string photoPath) { if (photoPath == null) throw new ArgumentNullException(nameof(photoPath)); if (File.Exists(Path.Combine(_serverPath.ServerPath, photoPath))) { File.Delete(Path.Combine(_serverPath.ServerPath, photoPath)); } } ``` This are all functions what ImageServis consist. If we want to save photo we have to create new Controller. I will name it ImageController: <center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png) </center> ``` public class ImageController1 : Controller { private readonly ImageService _imageService; public ImageController1(ImageService imageService) { _imageService = imageService; } [HttpPost] [Route("image")] public async Task<IActionResult> SaveImage(User user, IFormFile image) { var filePath = Path.GetTempFileName(); using (var stream = new FileStream(filePath, FileMode.Create)) { await image.CopyToAsync(stream); var avatar = _imageService.SaveImage(user, stream); } return Ok(); } } ``` Controller has injected imageService using Dependency Injection. The Post method i taking as parametr IFormatFile, which is new interface from ASP.NET Core. This is the end, now You know how to correctly save image using ASP.NET Core 2.0. #### Curriculum - [Refresh Token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api) - [Connection with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core) - [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0) - [Custom Error Handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0) <br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0">Utopian.io - Rewarding Open Source Contributors</a></em><hr/>
json metadata{"community":"utopian","app":"utopian/1.0.0","format":"markdown","repository":{"id":17620347,"name":"Home","full_name":"aspnet/Home","html_url":"https://github.com/aspnet/Home","fork":false,"owner":{"login":"aspnet"}},"pullRequests":[],"platform":"github","type":"tutorials","tags":["utopian-io","tutorial","utopian-io"],"users":["babelek"],"links":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png","https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api","https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core","https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0","https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0"],"image":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png","https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png"],"moderator":{"account":"rufans","time":"2018-01-26T03:30:44.754Z","reviewed":true,"pending":false,"flagged":false}}
Transaction InfoBlock #19305132/Trx fe4981da317bf3b58055d34abc805886bea55637
View Raw JSON Data
{
  "trx_id": "fe4981da317bf3b58055d34abc805886bea55637",
  "block": 19305132,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-26T03:30:54",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "utopian-io",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "title": "How to save image on the serwer using ASP.NET Core 2.0",
      "body": "\n#### What Will I Learn?\n\n- You will learn how to correctly save image on the server using ASP.NET Core. I will show You how to save original image and his smaller copy. I will use avatar and thumbnail as example. What is more this tutorial will show you how to save image made directly from smartphone, set him correctly position and save, resize and delete old.\n\n#### Requirements\n\n- C#\n- ASP.NET\n- Visual Studio 2015+/Visual Studio Core\n\n#### Difficulty\n\n- Intermediate\n\n#### Tutorial Contents\nAt the beginning we have to create new project. I will create new ASP.NET Core 2.0 Web API project. I will show you how do it using Visual Studio 2017.\n![project_1.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg)\n\n![project_2.JPG](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg)\n\nIn the new project I will create new folder with one class. It will be ImageService class, in this class we will define the whole logic for image management.\n\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png)\n</center>\n\nIn this service we have main function witch is: SaveImage. This function is define in this way:\n```\npublic async Task<string> SaveImage(User user, Stream imageStream)\n        {\n            if (imageStream == null || imageStream.Length == 0)\n            {\n                throw new ServiceException(ServiceErrorCodes.InvalidPhoto, \"There is no photo.\");\n            }\n\n            if (imageStream.Length > 5120000)\n            {\n                throw new ServiceException(ServiceErrorCodes.InvalidPhoto, \"Photo cannot be bigger than 5120000 bytes.\");\n            }\n\n            string[] photos;\n\n            try\n            {\n                photos = SetThumbnails(imageStream);\n            }\n            catch (ArgumentException)\n            {\n                throw new ServiceException(ServiceErrorCodes.InvalidPhoto, \"Invalid file format.\");\n            }\n\n            if (photos != null)\n            {\n                bool userHasThumbnail = user.WebThumbnail != null;\n                var oldPhoto = user.WebThumbnail;\n                var oldThumbnail = user.Thumbnail;\n                if (userHasThumbnail)\n                {\n                    DeletePhotoIfExist(oldPhoto);\n                    DeletePhotoIfExist(oldThumbnail);\n                }\n            }\n            return user.Thumbnail;\n        }\n```\nAs parameters take image as stream and user. User because we will save this image as his avatar.\nAt the beginning we have to check if stream i null or has no length, then if the image is too big.\n\nIn this function we have few more functions, the first one, and the most important is \"SetThumbnails()\"\n```\n public string[] SetThumbnails(Stream imageStream)\n        {\n            var originalImage = Image.FromStream(imageStream);\n\n            if (!ValidateImageFormat(originalImage))\n            {\n                throw new ArgumentException();\n            }\n\n            SetCorrectOrientation(originalImage);\n\n            var photoId = Guid.NewGuid().ToString();\n\n            var mobileThumbnail = $\"Content/Photos/Users/Thumbnails/500/{photoId}.jpg\";\n            var webThumbnail = $\"Content/Photos/Users/Thumbnails/100/{photoId}.jpg\";\n            CreateAndSaveThumbnail(originalImage, 500, mobileThumbnail);\n            CreateAndSaveThumbnail(originalImage, 100, webThumbnail);\n            originalImage.Dispose();\n\n            return new[] { webThumbnail, mobileThumbnail };\n        }\n```\nAs I said earlier we will validate our image if he has correctly format and right position.\n\nValidation image format:\n```\n private static bool ValidateImageFormat(Image image)\n        {\n            if (ImageFormat.Jpeg.Equals(image.RawFormat))\n            {\n                return true;\n            }\n            if (ImageFormat.Png.Equals(image.RawFormat))\n            {\n                return true;\n            }\n            if (ImageFormat.Gif.Equals(image.RawFormat))\n            {\n                return true;\n            }\n            if (ImageFormat.Bmp.Equals(image.RawFormat))\n            {\n                return true;\n            }\n            return false;\n        }\n```\nNow we have to  set correct image orientation, I'm using this function because photos made by samsung and directly save on the server are rotate about 90 degrees, I don't want to display photos like this, so I rotate them.\n```\nprivate static void SetCorrectOrientation(Image image)\n        {\n            //property id = 274 describe EXIF orientation parameter\n            if (Array.IndexOf(image.PropertyIdList, 274) > -1)\n            {\n                var orientation = (int)image.GetPropertyItem(274).Value[0];\n                switch (orientation)\n                {\n                    case 1:\n                        // No rotation required.\n                        break;\n                    case 2:\n                        image.RotateFlip(RotateFlipType.RotateNoneFlipX);\n                        break;\n                    case 3:\n                        image.RotateFlip(RotateFlipType.Rotate180FlipNone);\n                        break;\n                    case 4:\n                        image.RotateFlip(RotateFlipType.Rotate180FlipX);\n                        break;\n                    case 5:\n                        image.RotateFlip(RotateFlipType.Rotate90FlipX);\n                        break;\n                    case 6:\n                        image.RotateFlip(RotateFlipType.Rotate90FlipNone);\n                        break;\n                    case 7:\n                        image.RotateFlip(RotateFlipType.Rotate270FlipX);\n                        break;\n                    case 8:\n                        image.RotateFlip(RotateFlipType.Rotate270FlipNone);\n                        break;\n                }\n                // This EXIF data is now invalid and should be removed.\n                image.RemovePropertyItem(274);\n            }\n        }\n```\nIf we have correctly oriented photo we can save it.\n\n```\nprivate void CreateAndSaveThumbnail(Image image, int size, string thumbnailPath)\n        {\n            var thumbnailSize = GetThumbnailSize(image, size);\n\n            using (var bitmap = ResizeImage(image, thumbnailSize.Width, thumbnailSize.Height))\n            {\n                bitmap.Save(_serverPath.ServerPath + thumbnailPath, ImageFormat.Jpeg);\n            }\n        }\n```\n\nWe will save original and one smaller photo, so we have to resize it:\n```\nprivate static Size GetThumbnailSize(Image original, int size = 500)\n        {\n            var originalWidth = original.Width;\n            var originalHeight = original.Height;\n\n            double factor;\n            if (originalWidth > originalHeight)\n            {\n                factor = (double)size / originalWidth;\n            }\n            else\n            {\n                factor = (double)size / originalHeight;\n            }\n\n            return new Size((int)(originalWidth * factor), (int)(originalHeight * factor));\n        }\n```\n```\nprivate Bitmap ResizeImage(Image image, int width, int height)\n        {\n            var result = new Bitmap(width, height);\n\n            using (var graphics = Graphics.FromImage(result))\n            {\n                graphics.CompositingQuality = CompositingQuality.HighQuality;\n                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;\n                graphics.SmoothingMode = SmoothingMode.HighQuality;\n\n                graphics.DrawImage(image, 0, 0, result.Width, result.Height);\n            }\n\n            return result;\n        }\n```\nNow we have complete logic for saving images, at the end I will show you how to delete photos from server:\n```\n        public void DeletePhotoIfExist(string photoPath)\n        {\n            if (photoPath == null) \n                throw new ArgumentNullException(nameof(photoPath));\n\n            if (File.Exists(Path.Combine(_serverPath.ServerPath, photoPath)))\n            {\n                File.Delete(Path.Combine(_serverPath.ServerPath, photoPath));\n            }\n        }\n```\nThis are all functions what ImageServis consist. If we want to save photo we have to create new Controller. I will name it ImageController:\n<center>![image.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png)\n</center>\n\n```\npublic class ImageController1 : Controller\n    {\n        private readonly ImageService _imageService;\n\n        public ImageController1(ImageService imageService)\n        {\n            _imageService = imageService;\n        }\n\n        [HttpPost]\n        [Route(\"image\")]\n        public async Task<IActionResult> SaveImage(User user, IFormFile image)\n        {\n            var filePath = Path.GetTempFileName();\n\n            using (var stream = new FileStream(filePath, FileMode.Create))\n            {\n                await image.CopyToAsync(stream);\n                var avatar = _imageService.SaveImage(user, stream);\n            }\n\n            return Ok();\n        }\n    }\n```\n\nController has injected imageService using Dependency Injection. The Post method i taking as parametr IFormatFile, which is new interface from ASP.NET Core.\n\nThis is the end, now You know how to correctly save image using ASP.NET Core 2.0.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n#### Curriculum\n\n- [Refresh Token](https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api)\n- [Connection with MSSql](https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core)\n- [Email sending](https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0)\n- [Custom Error Handling](https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0)\n    \n\n<br /><hr/><em>Posted on <a href=\"https://utopian.io/utopian-io/@babelek/how-to-save-image-on-the-serwer-using-asp-net-core-2-0\">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>",
      "json_metadata": "{\"community\":\"utopian\",\"app\":\"utopian/1.0.0\",\"format\":\"markdown\",\"repository\":{\"id\":17620347,\"name\":\"Home\",\"full_name\":\"aspnet/Home\",\"html_url\":\"https://github.com/aspnet/Home\",\"fork\":false,\"owner\":{\"login\":\"aspnet\"}},\"pullRequests\":[],\"platform\":\"github\",\"type\":\"tutorials\",\"tags\":[\"utopian-io\",\"tutorial\",\"utopian-io\"],\"users\":[\"babelek\"],\"links\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png\",\"https://utopian.io/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api\",\"https://utopian.io/utopian-io/@babelek/how-to-connect-asp-net-core-2-0-project-with-mssql-database-using-entity-framework-core\",\"https://utopian.io/utopian-io/@babelek/how-to-send-email-using-asp-net-core-2-0\",\"https://utopian.io/utopian-io/@babelek/how-to-make-custom-error-handling-in-asp-net-core-2-0\"],\"image\":[\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827765/g5iss7rsg77ehpsdgppx.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516827769/bp77yqypijk4r5tlvtuc.jpg\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516828177/wz1psjildgfycqgtmcoj.png\",\"https://res.cloudinary.com/hpiynhbhq/image/upload/v1516829370/uknd34qlzns7ugx3ezsz.png\"],\"moderator\":{\"account\":\"rufans\",\"time\":\"2018-01-26T03:30:44.754Z\",\"reviewed\":true,\"pending\":false,\"flagged\":false}}"
    }
  ]
}
2018/01/25 00:56:09
votermvanyi
authorbabelek
permlinkhow-to-save-image-on-the-serwer-using-asp-net-core-2-0
weight10000 (100.00%)
Transaction InfoBlock #19273248/Trx 14dc1afc001005d9c8143ae9a3bc6838e57680e8
View Raw JSON Data
{
  "trx_id": "14dc1afc001005d9c8143ae9a3bc6838e57680e8",
  "block": 19273248,
  "trx_in_block": 30,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-25T00:56:09",
  "op": [
    "vote",
    {
      "voter": "mvanyi",
      "author": "babelek",
      "permlink": "how-to-save-image-on-the-serwer-using-asp-net-core-2-0",
      "weight": 10000
    }
  ]
}

Account Metadata

POSTING JSON METADATA
None
JSON METADATA
None
{
  "posting_json_metadata": {},
  "json_metadata": {}
}

Auth Keys

Owner
Single Signature
Public Keys
STM5YG2e4bvsowZ8vDGZgV4faWMvyqBqAZvixZjqfopbaQHr4m3dn1/1
Active
Single Signature
Public Keys
STM6dDZ9fXt1ypFJPpzBPrdkahZQddtiJgvtsq6T8kBzZbrnRq3h31/1
Posting
Single Signature
Public Keys
STM5k3yCExVHVZoceb85CiiE7zykhUnTsJSChcXC2F2rUNM8rTHpL1/1
App Permissions
Memo
STM7LD6HaCJDWL6QiJXZWtDaGQzbQzAteyBWs2dz7hViB8SZaEMhc
{
  "owner": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM5YG2e4bvsowZ8vDGZgV4faWMvyqBqAZvixZjqfopbaQHr4m3dn",
        1
      ]
    ]
  },
  "active": {
    "weight_threshold": 1,
    "account_auths": [],
    "key_auths": [
      [
        "STM6dDZ9fXt1ypFJPpzBPrdkahZQddtiJgvtsq6T8kBzZbrnRq3h3",
        1
      ]
    ]
  },
  "posting": {
    "weight_threshold": 1,
    "account_auths": [
      [
        "busy.app",
        1
      ],
      [
        "utopian.app",
        1
      ]
    ],
    "key_auths": [
      [
        "STM5k3yCExVHVZoceb85CiiE7zykhUnTsJSChcXC2F2rUNM8rTHpL",
        1
      ]
    ]
  },
  "memo": "STM7LD6HaCJDWL6QiJXZWtDaGQzbQzAteyBWs2dz7hViB8SZaEMhc"
}

Witness Votes

0 / 30
No active witness votes.
[]