플러터 컴포넌트 제작기-로그인

enoch·2021년 8월 9일
3

플러터

목록 보기
7/17
post-thumbnail

일단 로그인은 굉장히 많이 필요한부분이기때문에 만들어두면 좋겠다 싶어서 만들었지만, 언제나그렇듯.. 플러터는 자료가 별루 없어서 막만들어본거라 이게 정답이 아닐가능성이 매우~~ 높다.

일단 로그인을하려면, 백서버가 필요하니 간단하게 백서버를 node로 만들어 보았다.

velopert님의 jwt/node.js 로백서버 만들기

일단 로그인을하려면 로그인창이 필요하기때문에 대충 로그인 창을 만들었다

일단 내가 로그인을 만들어본게 리액트밖에없기때문에 리액트에서 로그인을 할때를 생각했다.

로그인요청 > (에러처리) > 로그인완료되면 axios 디폴트 헤더에 토큰넣고 > 스토리지저장하고 > 로그인끝!

그냥 간단하게 요약하자면 이렇게되는데... 일단 플러터에서 http 요청시 디폴트값을 설정하는게 따로 없고, 그냥 client 를 상속받아서 하나의 client class를 만들어서, 그 클라이언트가 요청을 보낼때마다 헤더를 집어넣어주는방법이 있다..조금귀찮...

그래서 먼저 클라이언트를 만들어주었다.

class MClient extends BaseClient {
  Map<String, String> _defaultHeaders = {};
  Client _client = new Client();

  MClient();

  @override
  Future<StreamedResponse> send(BaseRequest request) {
    return _client.send(request);
  }

  @override
  Future<Response> get(Uri url, {Map<String, String>? headers}) {
    return _client.get(url,headers: _mergeHeader(headers));
  }

  @override
  Future<Response> post(Uri url,
      {Map<String, String>? headers, Object? body, Encoding? encoding}) {
    return _client.post(url, body: body, encoding: encoding, headers:_mergeHeader(headers));
  }

  Map<String, String> _mergeHeader(Map<String, String>? headers) {
    return {..._defaultHeaders, ...?headers};
  }

  void setHeader(Map<String,String> headers){
    _defaultHeaders = headers;
  }
...
...

이런식으로 get,post등등의 요청들을 오버라이드해줘서 집어넣어주면끝..

하지만. 매번 새롭게 client를 만든다면.. 헤더를 매번넣어준다면?? 의미가없을테니깐 provider를 만들어서 앱이 실행했을때 client를 하나 생성해주고, 그때 생성한 클라이언트로 돌려쓰면 조금 편해지니깐...

class AuthProvider extends ChangeNotifier{
  MClient client = new MClient();

  void setClientHeader(Map<String,String> headers){
    client.setHeader(headers);
  }
}

대강 이런식으로 지정해주었다..

이프로바이더를 조금 안전한(?) 스토리지에 넣으면 자동로그인도 될꺼같다.
이건 플러그인이있다고 본것같은데.. secretLocal어쩌구저쩌구였던거같은데.

무튼..

이제 본격적으로 로그인을 하려면

static Future<String> passData(Map<String, String> data,
      MClient client) async {
    final response = await client.post(
        Uri.parse("${ConstValue.backEndURI}/api/auth/login"), body: data);
    final res = jsonDecode(response.body);
    if (response.statusCode == 200) {
      client.setHeader({"access-token": res["token"]});
      return "로그인 되었습니다";
    }
    throw res["message"];
  }

요런식으로 하면된다. 이상하게 보낼때는 json으로 안바꿔도 되는데 받으면 json을 디코드해줘야된다.. 이부분은 좀더 공부해봐야겠다.

그리고 dart언어에선 throw new Error(어쩌구)가 아니여서 조금당황했다.

거의 대부분 저렇게쓰길래 당연히 얘도 그럴줄알았는데 그냥 다짜고짜 문자열넣으면 나온다.

try {
      await API.passData({
        "username": _id,
        "password": _password,
      }, client);
      Navigator.of(context).push(MaterialPageRoute(builder: (context)=>CheckPage()));
    }catch(e){
      print("error");
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString()),backgroundColor: Colors.red));
    }

이건 로그인 버튼을 눌렀을때 부분인데. throw되면 아래 스낵바로 이쁘게오류가나온다

요로코롬~

토스트를쓸라고했는데 걔는 공식위젯이아니라서 요로코롬잘안나오더라.. 걔문서 찾아보기 조금 귀찮기도하고, 스낵바가 이쁘기도해서 얘로 적용!

마지막으로

velopert님 글에서 만든 check api로 들어가서 헤더가 잘적용됬는지 확인하면 끝


잘적용됬다.ㅎㅎ

profile
플러터존잼

0개의 댓글