mergeconflict217 James: [00:00:00] Frank, I thought I told you not to try to implement your own identity services. Didn't we have an entire podcast where we literally talked about how not to do this and that you should just use grids as authentication metrics. Frank: [00:00:21] I love that episode so much. We're just brainstorming, uh, authentication methods for, Ooh, is this episode nine of the great turnip trilogy? That's not a trilogy James: [00:00:33] almost rank I'll let me, I'll give you a quick turn up update here. Quick, turn up, update for the peeps. Um, on the pod. Um, I have officially, you know, I had to, I actually, before I went through all the shenanigans, going into the inept purchases and going freemium. Uh, I found that I needed to upgrade my in-app purchase plugin to a brand new version of the Android billing libraries. Now, traditionally, these libraries were shipped externally as interface libraries that you would buy into services. It was bananas, they're called Adal files, but now they have an official library. So I had to work with John Dick from the team. He created the, he literally created the bindings and did everything for me. And then two days later, Google released version 3.0. So I went through all that and it's a whole new API, but he made it. Beautiful. He async the crap out of it. It's like absolutely stunning, but everything is different. They have this crazy new thing where you have to acknowledge the purchase. The purchase and purchases can be made like at a store in some countries so they could buy it. But then you're supposed to revalidate it within three days. I'm like, this is in that purchases have gone crazy, but I'm at the point now is literally on a hike with Heather, Jen. I said, I want to finish this app by labor day. Maybe I'll get it done. We will see. Um, but anyways, that's the, that's the update, but no, no more. Turn of tracking, more, more grids, less squids, less squids, more identity. Frank: [00:02:02] More goods. In my case, I was inspired by our episode and I was like, my apps need more of these. Well, I mean, we just, why don't we have more random data throughout our apps? Yeah. Well, so you mentioned identity services and I want to clarify a little bit, I think there is lowercase identity services where we're just talking about users counts basically, and then there's. Capitalized identity services, which is an asp.net technology. In my case, an asp.net core or technology, because I'm building a website, James, I'm supposed to be a mobile division, but I keep building websites. It's silly, but this is going back to I'm building a landing page for my app. It's something we talked about, you know, time doesn't exist. It was probably. 8,000 years ago or something about that, but we're talking about landing pages. I wanted to build a website. I want it to use accounts and I decided I wanted to implement asp.net core identity services, trademark registered Microsoft product 2020. James: [00:03:06] Now, from my understanding, you just boot a visual studio. I've done this recently. You say, give me a new asp.net core website. There's a check box that says, give me authentication. And then you're done. I mean, so three minutes into the podcast. You're done and we're done. We're good. We're good. Here. Frank gets a checkbox. It's a checkbox. Frank: [00:03:25] Where were you a week ago, James? No. Yeah, it's even, um, even if you're on like Linux or something, you can.net new, uh, magical app. I forget what the template name is, but there is a template in there that has just a full website that has like all that stuff kind of baked into it and ready to go. Uh, you're going to hate me for what I'm about to say. Um, my problem with it is that all uses entity framework and I am an old school database person, and I find identity framework confusing for my simple mind. I like to write my select statements and move on with my life and, okay, James: [00:04:10] well, I was going to say, you know, identity or not identity service, but, um, Any framework, it can set up upon other things such as SQL database or SQL server, other things you're just like a fan of a code first approach. You don't like the migration. I'm going to have Jeremy come over onto Frank: [00:04:28] the podcast. We should do a podcast. Cause it's funny. Um, migrations is always the stumbling block. Oh RMS, uh, optic relational mappers. So, you know, I have my SQL Lite library and one thing that I'm most proud of and it is that handles migrations for you. It's a code for it. So I don't think it's fair to say that I don't like a code first approach. Um, what I think in this case was I've found entity framework a little bit too big and a little too confusing for me. And I wanted a simpler database layer that I did understand. James: [00:05:04] Okay. I mean, I don't think that that's bad in any way and it's, it's your website, so you should be able to do that. And from my understanding, it has to be on the core is relatively flexible. Now I will say one approach. I do like an asp.net, a core in general, as a non web developer is I. I, and I am, I can get feedback on this from the listeners, but I sort of enjoy the prescriptive, uh, approach that they have or the recommended built in paths that they often have. I, you know, I look@mostofwhatasp.net core does, and almost everything is interface based and injected through their dependency service, which means you should be able to. Register anything and sort of do anything and swap pieces in and out for, for my understanding. Now I will say I am on the ASP okay. Core documentation and under authentication. It is. No, there's a lot of sections. One, two, three, four, five, six, seven, eight, nine, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 2021, 22, 23, 23, 24, 24. That's all that's authentication. I didn't even get to authorization. Is that even different? Frank: [00:06:20] Correct? No, they are separate. They are separate concepts and core. I have to authenticate James: [00:06:25] to authorize. Frank: [00:06:27] Absolutely. Yeah, you can't authorize someone unless you know who they are. So, I mean, we're joking, but we should actually maybe define these. So authentication is proving who you are authorization is, are you allowed to access this resource? They are actually separate concepts and all that. So when you were saying, is it relatively flexible change? It's insanely flexible. It's maddening, maddening, flexible. It's annoying. Engli. Flexible. I should say actually as a beginner, because you're supposed to read those 21 docs, I guess, you know, the worst part of those docs at the top, it's like three minute read and it's like 10,000 words and code samples. You're like, Oh yeah, three minute read how Microsoft, what kind of geniuses are you measuring over there? James: [00:07:15] Yeah. So the identity part you're correct it. Isn't using API with some user interface that the users log in. If we're going to simplify the three minute reeks, it does say 17 minutes. Okay. TJ's users, passwords profile, data roles, claims, tokens, email, and more. Now. You can handle that yourself, right? You can have a, a data store with user data, or you could use third party providers like Facebook, Google, Microsoft, Twitter, or things like that. Now what I'm reading here, Frank, and I'm curious, because I know without an, a core three, they have obviously a built in connectors for like Azure, a D, but also this thing called identity server. And it's funny that we're talking about identity services that are built into. Asp.net core, but then there's identity server, which is. An open ID connect or OAuth two provider on top of it. Now, if anyone is confused at this point, it's okay. It don't worry because authentication is hard. Frank: [00:08:15] We're going to get through this. We can do this now. I actually can't speak too intelligently on identity servers. I know of the technology. I know the goals they're trying to do. It's kind of the trick that, um, get hub and Facebook are doing when you're able to log into third party services with those. But, um, I don't think most people will run an identity server unless they're in a giant corporation. And in that case, I think giant corporations tend to use other things for identity. So what I'm thinking about for my thing is more of a public style app interface, where I want a basic user accounts on my own site and maybe in the future allow log-ins from GitHub and Facebook and all that kind of stuff. So. I've been making database back websites since the nineties, I've been making user accounts systems since the nineties, you know, definitely roll your own. It's easy to set a cookie and it's easy to make a million mistakes with a user account system. So it's a little frustrating by me because I constantly, um, I'm debating between, do I really just do it myself and ignore all the authentication? Authorization stuff and asp.net. In fact, I believe that's the approach stack overflow took when they were very first running their system. Um, there were. Older versions of these services that we have today available. And they're like, no, we're just going to roll our own. Well, the thing is, there's a lot of good advantages to working with the identity services system, built into asp.net. And a lot of that is just it's debugged code. You know, James, like you fill in some interfaces and bingo Presto, it should just work and that's kind of nice. Someone else wrote it. James: [00:10:03] Yeah, I've always been a very big fan of the attributes that they have. Um, only when you sort of, you know, scaffold your application out. It'll give you all, it'll basically give you not, not basically, it will give you a registration log in, log out, registration, confirmation. I think it can even do emails. I can do too fast, you know, as big as you add anything. Um, but what I like on it is that users can have, um, Can have roles. So like admin roles, but additionally often on pages or on epi is you need to, you can Mark those with like allow anonymous or have to be authenticated. And then additionally, there's built in helpers that enable you to you to get data. About who that user is. So you can say is this user and admin a specific role that, that comes into the system and you just add an attribute, like authorize and guess what? They gotta be authorized to do it. Right. It's not like you're right. In any magical, you know, in a mobile app. You're like, okay, well, if they logged in and they're an admin and like, this is here, like the screens in the app. So like someone could maybe get to it and they got to get the data from the server and you've got to do multiple things. Like, no, like this. Authorize and you're done, right? So there's some nice things there from, from at least what I've used of it. And I'm sure there's more that we can do Frank: [00:11:25] no 100%. So when I think back to 100% rolling my own kind of account system, you lose out on all of that is p.net integration. And when you're losing out on that kind of integration, there's stuff, it's like, why are you using a framework at all? Like use the framework or don't use the framework. And I tend to think as much as I love reinventing the wheel and everyone knows how much I love it. Um, I try to use the framework as much as I can. And yeah, those authorize attributes are amazing. You just throw them out in a part of the website and asp.net takes care of the rest, making sure that, uh, people well bounce off to a different URL, you know, to do a login and then it'll bounce back to the page. You know, it's, it's not hard to write that stuff, but it's taken care of for you, but in order to, Oh, and I should say you were mentioning, um, Just taking on like extra information. There is this user object or property and almost all contexts in ASB, Donna. So if you write a, a controller you have on there, if you write a view, there's one there. If you write a razor page, you have one there. I'm curious if blazer has one. A user object, James: [00:12:38] but yeah. Frank: [00:12:39] Yeah. Cool. It's probably the same user object and what's neat is when you're logging people in, you can add what they call claims to this object, which is just data. But you can kind of query on the data. You can assert it. And that gets into the kind of authorization stuff that we were talking about, but it's also just a nice little data store to just dump a bunch of data that you want to keep around with the logged in user. James: [00:13:07] So. If it has all these nice things. In fact, you know, the entity data types that are in you get user tokens, user login and roll claims, user roles, you get a row or user, right? Like you were saying, you just didn't want any of it. You're just like, ah, no, thank you. Thank you, Microsoft. But no, thanks. I don't want your data. I don't want your data types. I'll get my own user. You think, you know what a user is? Microsoft on Frank courier. Let me show you how it's done. Is that what happened? Exactly. Frank: [00:13:37] You've known me for too long. That was exactly the narrative going on in my head. You don't know me? Do what I James: [00:13:44] want. Tell me Microsoft. Frank: [00:13:47] Well, okay. Well, okay. So there's no free lunch in anything and all those cool features you were talking about like two factor authentication and. Emails and get hubs and all that stuff that comes with a heavy database load, a password resets, all that kind of stuff. And I don't know how many tables, uh, the entity framework wants to create for all this stuff. But somewhere between five to 10, it's a lot of tables. It's a good amount of data and you got to manage that stuff and deal with it and deal with it within that context. So it wasn't so much that. You know, I wanted all this identity stuff for sure, but I didn't need it all in the beginning. I didn't need the two factor stuff. I didn't need the external stores. And I like to keep my code as small as possible. It's the only way I can manage things. And that's why I wanted to implement my data. I I'm my own data layer, I should say. And plus all those doc documents kept saying, it's no problem, man. You can implement your own data layer for this stuff. It's easy PV. We have a inversion of control. We have services and things like that. So it should totally be easy. They filled me with confidence. James: [00:15:03] So I would, I would imagine I'm looking here. It looks relatively straight forward. I don't know. Where you stumbled or what issues or you ran into Frank, but literally you should just be able to bingo back. I mean, did you not, did you, so what happened here? You went through the docs. I'm assuming that this wasn't documented or was it documented on how to do this? Frank: [00:15:22] There are some documents on this, but they tend to take a few shortcuts in the examples that don't quite work out in production when you're actually trying to implement it and things like that. So it's one of those things where it's documented, but there are a lot of little gotchas along the way. Plus, you know, me, I didn't start with docs who starts with the docs. You start with IntelliSense James, you, you type authenticate and you see what comes up. Sure. Let me scroll through the list. And you're like, Ooh, I like that name. That sounds interesting. I wonder what that can do. That's how you code. James: [00:15:56] When we think about it, you know, creating a user store doesn't seem too complicated, right? Because it's, it's just whatever data you want and it could be as easy as your username, email password. Right. And of course, you're going to salt that puppy, or you're going to hash it out. You're going to, you know, you're going to, you're gonna encrypt that thing, um, across the wire, but ideally it, at that point, it sorta becomes. operations, I guess, to your data store. I would I'd imagine. Frank: [00:16:23] Yeah, a hundred percent. So the way this goes is you actually. Are required to define a user type, no big deal. Just any old object. They're actually, um, the it's used as a generic parameter to a lot of functions, but there aren't any constraints on it. So it really can just be whatever you want it to be. So the big thing that you have to implement is the data store for that object so that the identity service can. You know, look up an email, look up their name, check their password, all that kind of stuff. It's exactly what you would think. Like you were saying, the crud operations, it really maps nicely to that. So those are the two things that the docs say you have to provide future object. And the, I think it's called I user data store, but I don't have the docs in front of me right now. And I've already forgotten. Okay. So what do you do? You type in a public class? My data store, colon, I user data store and the nice little Roslyn thinner implements, a whole bunch of functions that throw not implemented. And you're like, great. I got my identity system. No problem. I won't hear you. Uh, yeah, you go and you register that puppy. Uh, there's like a service registry that you do in the beginning of all asp.net apps. Say for a user data store of my cool app user object, instantiate this class. How much easier can it get, so you do that and you run it and you get 20 some odd errors. James: [00:18:00] I do. I do see this. Yeah. So there is, um, there is in fact there, this is how things are layered by the way. So you have your asp.net core application on top that I'm looking at documentation with boxes and that's how you know it's good colored. Uh, so this is a blue box asp.net core app. Now. The identity manager, that's built an asp.net. That's your user manager role manager. Now the, the bits and pieces you need to implement are the identity store data access layer. And then it is going to connect to the data store and is correct. You do need a bunch of stuff. In fact, I'm, I'm seeing here that you need to implement, uh, not that many you're right now that many I. Uh, I'm looking at the documentation. I believe it is just the user store. Maybe your roll, roll, roll types, perhaps. Frank: [00:18:49] Nope. Don't even James: [00:18:50] need that. Oh my goodness. Wow. The problem Frank: [00:18:52] is when it tries to instantiate your object, it's going to find a whole bunch of eyes, something or another is out there. Most of which are generic on your user type and it's not going to find them. James: [00:19:04] Oh, you mean exist? You mean the optional interfaces? Such as I use a roll store, I use her claim store. I use her passwords or I use her security sampler. I use her emails are I use her phone numbers for I queryable users are I use their logins? Are I use or two factor? Sorry. I use our lockouts. Are those the ones you're talking about? Frank: [00:19:20] No, those actually do sound optional to me, but there's a lot of those that you didn't list that aren't in fact optional that you really do need to. So, can you imagine what I did? I just started implementing them mall and there were at times tons. I can't remember the number, but not those optional ones. I didn't do any of that stuff, anything I'm just trying to get the database layer to work. And it was something like I'm going to go with 10 to 15. I don't remember, but it was a lot of these snails and it still wouldn't work. Oh, no. Yeah. Cause I would get up to this point where, Hey, I don't know how to implement half of these things. I don't know what the heck they're supposed to be doing. And I'm losing all the advantages of this code. That's supposed to be pre-written for me. What I didn't realize, James, is that in the service registration, there is a magical something like services dot, add identity. Pass it, your user object and you know what it does. It registers a whole bunch of classes for you. So you don't have to, you know how I discovered that randomly lucky. I think I might've copied and pasted some code off of a stack overflow. I really don't remember how, but when I found that function. Boy, did I feel James: [00:20:40] stupid? Yes. There is the magical app that add authentication app dot add authorization, and those are things that do quite amazing things. And you, and also has a meeting. Things are good friends over at Reagan. Wow. What a transition? Listen. Reagan helps thousands of customer centric, software teams detect, diagnose, and resolve performance issues faster, more efficiently. Are you. Creating your own user authentication store and database backend. Just like our good friend, Frank, listen, you may have issues. You may not maybe perfect the first time, but listen now is a time to plug Reagan into application. And for a limited time, if you switch your application monitoring to Reagan, maybe out there, boom, they'll give you up to $20,000. And free usage credit. That's amazing. It's never been a better time to make the switch, save thousands and empower your team with the visibility and insights they need to deliver flaw Wallace flaw, less customer experiences. Go to Ray gun.com/switch to apply for the $20,000 in free credit. That's reagan.com/twitter. Nope, not Twitch. raygun.com/switch terms and conditions. A poli. I'm just going to say that just because I'm assuming they do Frank: [00:21:57] that. They always apply. There's always terms James: [00:21:59] and conditions. I should say that like every, every sponsor returns and conditions, not, not, not, or, and terms and conditions, and if there's no conditions, Then there's there's somewhere on there. You've gotta find, you know, Frank: [00:22:14] are you sleepy, James? How are you James: [00:22:16] doing buddy? I'm so tired. I walked 20 hour, 10 miles a day up a big mountain. So Frank: [00:22:21] that's awesome. Absolutely fantastic. Well, I'll make my story short for you. So you don't fall asleep on me here. We're James: [00:22:28] only halfway in. Thanks a Reagan again for sponsoring this week's pod. All right, Frank. So hopefully people are enjoying this episode so far because I am. I am piling drawn this up now because you know, Frank, I am on the, like, here is you are right. That there, there are documentation. I'm looking at the docs right now. And it tells you all this stuff got to do. And, um, yeah, I think the problem here is of course, if you've already click the check boxes, you know, and check them, it's going to add all that stuff for you. So you're like, Oh, I have all this great stuff. And then boom, this makes sense. Frank: [00:23:05] Yeah, what I probably should have done. And I've, I should actually say this third attempt at implementing identity services. I don't want to sound like I'm that bad of a programmer, but sometimes I am, or just that bad at reading the document, but I'm kind of doing this episode because I'm so proud of myself for finally getting this thing going, um, It ended up not being too bad. So I think it's one of those things. It's once you have the knowledge it's okay. And I should have also gone back to the entity framework templates and compared my code to theirs, because obviously it was going to just be this one function that I'm dismissing, because why would they make you implement 20 different interfaces that make absolutely no sense I should have. And I did know, like, This can't be right. Like who would design an API to work this way? This is ridiculous, but at the same time, I didn't know what else to do. I was really back to like the new programmer position where you're like, this feels wrong, but I don't know what else to do. James: [00:24:05] Yeah, just keep going until it works. Usually that's what's I mean, usually it's like, well, yeah, needs, I know what was I, I was doing something one time and it was the same thing. Like I just kept adding, you know, it wasn't like if conditions, but it was like initialization methods. Like I'll just keep adding that. Like add that dependency. Yeah. That dependency, you know, like when you're registering your services and you're like, Oh, I forgot one. Oh, it's I think it's usually when I release a, Oh, you know, what it is is like, when I was doing the linker, like the linker gets really complicated, like right. And just keep that deal. I'll keep that. Just maybe keep that DLL, like just, yeah, forget that one. Skip that one. It's okay. Just gives you. And then sometimes you can get around it by initializing it. Like, you'll be like, okay, VAR, I equals type of whatever. Right. And then I can maybe type of this render type of that render. How about this vendor or someone please link our, keep it, keep it forever. Frank: [00:25:04] You're making me squirm a little bit. Please use the preserve attribute. Everyone. Just declare an attribute called preserve and you don't do whatever James is suggesting there. Um, yeah, I get you though, especially with, uh, the linker. I always start out with every class and then just delete them and delete until it stops working or something like that. So that's definitely the approach I was taking here, which is funny because once I implemented that function, that's literally the approach I would take. Because I just started deleting those 15 classes, like one by one, still working that leaked, that one, still working, delete that one, you know, really back to the beginning. So just to, uh, give people some closure, if you ever do find yourself in this position, uh, the, I was wrong about the user store. The one I ended up implementing is called I user password store. It's a lovely name. James: [00:25:56] That's descriptive. I believe it uses passwords for user Frank: [00:26:02] vocation. Is there James: [00:26:03] for sure. Very district it's one thing I like about C-sharp very descriptive names. I Frank: [00:26:10] right. Yeah. Um, and then you also are required to implement. Uh, some version of a sign in manager, the good news there is you really don't have to do anything. You can. There's a base class already. It's not an interface. So you can either use the base class or implement your own. So very little work to do there. Isn't that ironic you implement those two things and all of a sudden you have. Most, if not all of the power of identity services, minus all those throw, not implemented exceptions that I still have in my code for all the features. I don't quite support just yet. Yeah. James: [00:26:49] One day. Well, and the thing is, if you don't need them, then that's also okay, too. Right. That's the, one of the one things you were thinking about is like, Hey, I like my databases. I'll do my own database. And also I may not, I may not need all of this stuff. Frank: [00:27:06] Two factor authentication. I know it's becoming a norm, but do I really have to have two factor authentication? Like websites are becoming so complicated these days, the expectation level is so high. We used to just store plain text passwords in a text file. It was fine. People only broke into it once in awhile. James: [00:27:25] Don't do that. Please, please. Frank: [00:27:27] Don't do that. Giving bad advice. Don't worry. People's passwords were terrible back then. James: [00:27:31] Yeah, that's also true. Yeah, I. I will say that too. I mean, passwords are very outdated anyways. You know, the one that I enjoyed the most of passwords is I have my Microsoft account. Set up that it will just send a notification to my phone and I can just thumb print in, you know, and just authenticate that way. So I don't even have to type anything. It'll say, just send notification. I have my phone, which is right here and I just tap it and it's like, cool. You're in. I like that because what I found is I was doing demos a lot. And I was using my Microsoft account to log in on different demos. Cause you Frank: [00:28:11] know, you could James: [00:28:13] do that. And I, on Android, the browser would, would hide, hide it by default. But if I was reflecting iOS, the iOS default text box is not hot. It'll eventually hide it. It'll Frank: [00:28:26] show it shows each letter. James: [00:28:28] And then here's then here's what happened is that I would always try to hide it, but then I was doing a recording. I was doing a recording inside of channel nine. And I'm like, Oh, okay. Like, you know, we'll cut this out or we'll hide it behind, you know, not a big deal. And then I'm like everybody, every single producer back there just saw me type my password, you know? Cause no one can see, cause I'm not presenting to anybody, but I'm like, Oh, they'll just edit this out. And then I was like, I, and I type it in I'm like password one, two, three. And I was like, Oh my goodness. Like everybody now knows. So then I was like, I need to figure this out. So that's cool because it's almost like a form of two factor authentication because two factor off is like, Hey, enter your password and then go to your phone and, and press a button. And this one's like, Hey, Just press the button. Cause like what's the difference. What's literally the difference there. No difference. So Frank: [00:29:21] yeah. I love crazy logging accounts. I'm Marco Arment, ding. He has a wonderful idea of login systems where every time you want to log in, it sends you an email and you have to click a link. No passwords. James: [00:29:35] That's good. Frank: [00:29:35] So yeah. Prove your authentic identity with email and yeah. Kind of love it. We hate email, but I kind of love the idea. James: [00:29:44] Yeah, we, that one's genius. We use a, um, I've been testing out this, this streaming for like shows, stream yard, and we have a few producers and it's the same thing where it just sends you an email. That's really convenient because then you don't need to go and pass around the password to everybody. You can just put everybody on a distribution group and you're like, okay, cool. Like anybody can log in because everybody goes, this extension code. That means it's actually way less secure by the way. But Frank: [00:30:10] yeah, don't, don't leak that or, well, don't register that email, I guess would be the trick. They're correct, James: [00:30:15] but also fine. And I think that's cool. You know, I was using it for micro. My microblog because, um, uh, that also it uses the same system that, that marketed to you go and you enter your email address and sure enough, bingo, bingo. It does the same thing, which is funny Manton Frank: [00:30:32] Reese. Yeah. I'm definitely from the same community. I wonder who the originator was. James: [00:30:41] Should we should ask. We should get, we should get them on the pond. You can make that happen, right? Frank: [00:30:47] You can change. Okay, perfect. Uh, you, you have a good point though. Passwords are old. And definitely even when I was doing this, I was thinking, Oh, maybe I'll only allow get hub log-ins, you know, or something like that. And there is a good side to that, but password systems are relatively easy to implement. I think it's kind of a web standard to allow them. I don't. Like sites that force you into using third party ones and. I think that the password culture has improved drastically, please. Since the nineties, I don't know about you, but I don't know any of my passwords. They're all random numbers stored in some random number store encrypted thing who knows. Uh, so I don't. Feel too bad these days actually asking people to create user accounts in that regard. That's this is a website, not an app. When we were talking about your app and the goods and the amazing system we came up with there that says, I want. On 1990 style website here, you know, this is what I'm building. I want user account. That's James: [00:31:52] the problem. You know, the problem with third party OAuth providers is that like on the positive side, like you said, it makes it easier for people that are already logged into a service to log in the problem with them. Is that not everybody has that thing. So you can't just pick one, you can't just be like, Oh, let me get Twitter. Right. Um, because not everybody has Twitter and then whether they're gonna sign up for a Twitter account and then they sign up for another account or they just decide not to use your app. There is a. A default of at least always having username password. If I had to, I prefer that I'm a big fan. I used to be, let me just log in with Twitter or Google with everything, you know, and then you get to the website and you, you know, two, two years later and you're like, Oh man, which one did I sign in with? Right. And they've added 15 more now. There's like, you know, like, uh, maybe it was my Pinterest account. Maybe it was my, my, you know, I don't know this other account. And then. And then is that almost confusing to the end user? I'll always do username and password. Although, I mean, of course then they have my passwords. I'm assuming they're, they're salting and hashing and they're doing the right things and encrypting my password. I hope. I don't know, you can't win. Nothing is good. Frank. Everything is terrible. Frank: [00:33:05] Yeah. That's why you use a different password on every site and that's for your bank. Hopefully have a good bank for something like that. But it's funny when you're, when you're talking about those third party ones to this day, I don't know how to log into stack overflow into my account. Sometimes I go onto a computer and it's like log in and I click a button and then I click another button and it's like, Hey, you're logged in. I'm like, great. I have no idea how I did that because when stack overflow started, they were using open. I D was their suggested open ID provider and they've since gone under, they don't exist anymore. So. The way I access stack overflow doesn't exist, which is a conundrum because somehow I'm still able to log in. So I must have at some point assigned some other identity provider to help me log in. James: [00:33:52] How do I log in with stack? Overfund I'm trying to write it. Frank: [00:33:55] Yeah, because they didn't want to create user accounts. And to this day, I'm just like, You should have just created user accounts. I mean, they have user accounts. I just don't have user authentication. Maybe today they do, but definitely in the beginning they did not. James: [00:34:08] I don't, I don't think I can get in. Frank: [00:34:11] See you, sir. Good. The one thing I noticed is browsers are really aggressive about saving usernames and passwords because when I'm trying to like debug this code safaris constantly, do you want me to save this? Do you want me to say that I'm like, stop bothering me. I'm trying to debug code here and it's just being so aggressive about saving it. It's James: [00:34:32] true. It's very true. In fact, um, I, I use I've multiple password saving techniques. I have both Chrome and edge, so like they both double backup. So as soon as I create one user account, I go to the other browser log in saves and I'll save it in two browsers. Frank: [00:34:50] Nice. Yeah. Cool. James: [00:34:52] Then, then it's bad when you change your password and you're like, which date? That browser like, Oh no, here we go. That's fun. Frank: [00:34:59] That's why I'm stuck in the Apple ecosystem. Aren't they smart? James: [00:35:02] You know what? Just can't get out. You know what I, you know, it's very true. In fact who bought yeah. Who just gave Apple stupid money for extended iClouds or usage? This guy who's got 200 gigs of iCloud for no. Frank: [00:35:16] Oh, I guess you donating to the yeah. James: [00:35:20] Family. Oh, you know, you could do the, you can do the, the, the 99 cent one, right? That's the one that they want you to do. Like the it's like the it's like the 500 gig 500 megs or whatever, but then you honestly get the 200 gay sense family plan, and then you get family, family plans, or like family user accounts. I'm going to turn this back readily. They're like, right, right. Anybody can be in your family. You know what I mean? You could be in my family, Frank, and you can have access to my Apple news. Plus I got four, four months free. Frank: [00:35:53] You know what I don't like make it prove your relationship. Like if you were getting married in the U S you have to prove your relationship with immigration only James: [00:36:01] Amazon does for prime. Now you have to do both, both accounts have to it's tricky, Amazon, at least the last time I did, you both have to have the same address registered, and then the primary, the price. This is where they get you right there. Like that that's easy. Anyone can enter the addresses as it, but then the primary. Um, head of the household, their credit card, like needs to be like anybody else can use it. Like in the house, so Heather want it to, so you're like, you're not, I'm not adding you onto my Amazon products. Frank: [00:36:34] I want access to that credit card though. I'm liking this. Definitely. James: [00:36:39] I mean, I don't know if they do that still now, but that was definitely a thing we had gotten. So sidetrack Frank. Okay. So, Frank: [00:36:45] okay. I can bring it back because you had mentioned, um, salting and hashing passwords, and I just want to say. Yeah. Um, the nice thing identity services is that's kind of baked into it. So you're, you're never storing plain text passwords or anything like that. It's very, it doesn't really even ever give you access to the plain text password as far as I can tell. Oh, no, you have to pass it in when you're doing like your login form or something. I like that. But yeah, after that, it's all hashed. Um, and it's kind of cool that that's why I wanted it. I didn't, I want to write that kind of security code myself. I wanted Microsoft to write it and test it and all that kind of stuff. I'm pretty happy be where that, I guess is what I'm saying, James. Um, it's nice. It's nice that someone else thinks about security. So I don't have to. James: [00:37:34] That's very true. In fact, you know, for a long time, any of the demos that I did were all just log in with Twitter or Facebook or whatever. Cause I wasn't, I wasn't doing anything. Right. You know, I was just give me a user ID token and I'm done cause they're just sample projects. But when you need to do something real. You need to think about these things you need to think about, where am I storing my data? What additional providers am I going to be bringing? Do I want to factor off? Or, you know, maybe I don't need it now, but can I extend it? So maybe in the future it works out of the box. So it's definitely one thing to, um, just sort of think about then, Hey, it's more than a checkbox. There are some other implications here that I may need to, may need to think about when you're writing that code. Frank: [00:38:19] And there are some funny defaults. Like I'm one of those 15 to 20 classes I was talking about in the beginning that I was implementing. And I'll see the container world services world. You run into these interfaces that do one thing. They have one function on them. So it's basically a function you're registering a global function out there. And there's a funny one called normalize user identifiers and Microsoft default. Normalization is to put everything into uppercase. There are reasons they do this. I've been through the security lectures, mostly it's the Turkish language. That's at fault here with the way, uh, you put the, uh, darn I forgotten what it's, it's the letter I though, um, with a little, uh, kind of a posture thing instead of a dot the way you uppercase and lowercase staffing is tricky. Especially if you're not aware of how that culture works and how that language works. And so Microsoft always recommends upper casing, but. I'm an internet person. I prefer lower case. So it's funny. Uh, you can just, uh, implement that interface yourself. I forget what it's called, but something like I identify or normalization or something like that. And I call lower to lower and variant instead of to upper end. So that way I can get my database to look exactly how I want it to look. And I'm very sorry, everyone in Turkey, please just don't use usernames with that. I in them. Sorry, my bad. I think that's the only letter that honestly it, it breaks with. James: [00:39:54] So why didn't you just use the recommended path Frank, you need to change. Frank: [00:39:58] Uppercase. Uppercase is shouting. It's bad internet culture to use uppercase. Microsoft should notice. James: [00:40:03] Oh my goodness. I guess you could replace that eye with something else. Frank: [00:40:07] Well, the truth is because I was putting it in URLs also. And so I just wanted the URLs to just look nice. James: [00:40:14] So you're happy. It sounds like you're happy Frank, Frank: [00:40:17] because, because it did being a minimum amount of code. That's what finally made me happy about it. If it was left with those 50, if I was left with those 5,020 classes. I would have felt terrible. Like what is the service? It's not doing anything for me, but as it is, I only implemented maybe five of the functions, the rest still throw, not implemented. And the whole thing works great. It's really nice authentication with authorization, with roles, all that kind of crazy stuff, just by implementing a data store. That's nice. James: [00:40:52] That sounds like a good blog post. Frank: [00:40:55] Yeah, I probably should write all this James: [00:40:59] just so you don't forget for next time. Frank: [00:41:01] Okay. Yeah. I actually, during all of this, I kept thinking like I should clone this project right now. Put it up as a get hub so I can use it as a template from then on, because it was like in a nice state with like a very simple database layer, a very simple user authentication system, you know, is just a good starting point for most kind of web apps. James: [00:41:20] I like that. What's your database. Frank: [00:41:22] Uh, Postgres James: [00:41:24] post-grads Frank: [00:41:25] yeah. You know that one? I know I've James: [00:41:27] heard of it, but Frank: [00:41:29] it's kind of like, yeah, it's definitely a SQL. Yep. It's kind of a variation SQL, SQL. Like they tried really hard to implement the actual SQL standard. And it's just a, just a small database. I'm mostly just using it for user accounts, but I wanted something simple and manageable. I'm running it all under Dockers. So it really kind of doesn't matter. I should be able to switch out the database layer easily. And then finally, for those who I know will ask for an ORM, I'm actually using dapper. Which is the ORM that stack overflow uses, which I find to be very pleasant to use James: [00:42:03] DAP P E R Frank: [00:42:05] D a. Yep. Uh, it's. It's um, less sophisticated than SQL like dash net, but it gets the job done. James: [00:42:15] Very cool. Well, it's very. Uh, fascinating. Yeah, it is. It, it says@asimpleobjectmapperfor.net. And that's cool. Um, in general, it sounds like you went to stack overflow approach here, Frank, really at the end, the day, you're just like inspired and you're like, here we go. Frank: [00:42:31] Well, you have to, the stack overflow approach is simplicity and that is something I will always get in line with. Uh, they don't, they don't like to over-engineer things. And I really appreciate that. Plus they're very open and talk about this stuff. James: [00:42:46] And also there's a new gift package called dapper dot rainbow. And that's cool. Frank: [00:42:50] Oh, I should check that out. I have no idea what James: [00:42:52] that is. It's a trivial micro ORM implemented on dapper provides the crud helpers. Frank: [00:42:57] That's what it says. Oh, neat. Okay. So it's adding a few, a few more helpers. Yeah. Cause uh, the way dapper works is it's, it's not actually an object, relational mapper too much. It can only do basic value types. You're writing SQL the entire time. You're not writing link. You're writing text. Got it. James: [00:43:17] And that is what Frank likes. For some reason, I don't want Frank: [00:43:21] it. The nineties, man. It just feels good. Select star user, especially that password. Send that down to Jason. ClearTax just kidding everyone. Don't do any of that. James: [00:43:32] Frank's over there hacking the planet. No, one's going to trash planet. No, one's going to trash his rights. Oh my goodness. Frank: [00:43:42] I'm all. It feels good. You know, like. Want to have a hard time maintaining. That's why I'm really pressuring myself, simple code, simple code that I understand. Like there's no magic happening here except for a little bit of inversion of control. Okay. I'm done trying to justify my terrible decisions. James: [00:44:01] I think you're great. Frank. I love everything that you're doing. And so to our listeners, and of course, if you are going to implement your own. Crazy user tables. Let Frank know how you did it. Did you use dapper? Did you use Postgres? What did you use or did you just use, what's already built in check box and you're done right into the show. Go to merge conflict.fm or tweeted us merge conflict. FM is a Twitter clown, or we enjoyed this really silly and entertaining episode of merge conflict with some serious developer talk in it. That's what we bring each and every Monday. So until next time, this has been merged conflict and I'm James Monza Magno Frank: [00:44:40] I'm frankly, here. Thanks for listening.